Swift: Reusable Uiview in Storyboard and Sizing Constraints

Swift: Reusable UIView in storyboard and sizing constraints

The actual view hierarchy loaded from the nib file in your code is added via
self.addSubview(self.view). So, the frame of your self.view actually has no relationship with its parent, i.e. MyWidgetView.

You may choose either adding layout constraints through code or just setting its frame after being added as a subview. Personally, I prefer the latter. In my experiment, the following is what works for me. I am using Xcode 6.4, which I think is not the same one as yours.

required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)

if let nibsView = NSBundle.mainBundle().loadNibNamed("MyWidgetView", owner: self, options: nil) as? [UIView] {
let nibRoot = nibsView[0]
self.addSubview(nibRoot)
nibRoot.frame = self.bounds
}
}

Storyboard Constraints Don't Affect Custom UiView Size

I found the solution i use view.frame = self.bounds in init and the size automatically adjusts based on the constraints in the storyboard.

Subviews size issue - UIView related sizing in xib

I believe the view (UIView) does size itself so i dont think you will face this issue. Just try to not constrain the height and make sure you select appropriate stack view while doing this since you got multiple. Hope this helps as i assume that you are not using collection view for this matter!

Reuse a uiview xib in storyboard

Reuse and render a xib in a storyboard.

Tested with Swift 2.2 & Xcode 7.3.1

1 ---- Create a new UIView named 'DesignableXibView'

  • File > New > File > Source > Cocoa Touch Class > UIView

2 ---- Create a matching xib file named 'DesignableXibView'

  • File > New > File > User Interface > View

3 ---- Set the file owner of the of the xib

  1. select the xib
  2. select file's owner
  3. set custom class to 'DesignableXibView' in the Identity Inspector.

Setting a Xib's Owner to a Custom Class

  • Note: Do not set the custom class of the view on the xib. Only the File Owner!

4 ---- DesignableXibView's Implementation

//  DesignableXibView.swift

import UIKit

@IBDesignable

class DesignableXibView: UIView {

var contentView : UIView?

override init(frame: CGRect) {
super.init(frame: frame)
xibSetup()
}

required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
xibSetup()
}

func xibSetup() {
contentView = loadViewFromNib()

// use bounds not frame or it'll be offset
contentView!.frame = bounds

// Make the view stretch with containing view
contentView!.autoresizingMask = [UIViewAutoresizing.FlexibleWidth, UIViewAutoresizing.FlexibleHeight]

// Adding custom subview on top of our view (over any custom drawing > see note below)
addSubview(contentView!)
}

func loadViewFromNib() -> UIView! {

let bundle = NSBundle(forClass: self.dynamicType)
let nib = UINib(nibName: String(self.dynamicType), bundle: bundle)
let view = nib.instantiateWithOwner(self, options: nil)[0] as! UIView

return view
}

}

5 ---- Test your reuseable view in a storyboard

  1. Open your storyboard
  2. Add a view
  3. Set that view's Custom Class
  4. wait a sec ... BOOM!!

Xib Rendering Inside a Storyboard View Controller

Change the width of a UIView that already exists in Storyboard? Swift

I've just write an example , if your project is autolayout , you need to define width constraint for progressView , then you need to make an outlet connection from your constraint and then change this property at method

@property (weak, nonatomic) IBOutlet NSLayoutConstraint *ViewWidth;

in method:

 self.ViewWidth.constant =number;

Storyboard: align button in custom UIView to another button in parent UIView using auto-layout constraints?

No it is not possible to do what you are trying to do in storyboard. You would have to do it programatically.

Creating a reusable UIView with xib (and loading from storyboard)

Your problem is calling loadNibNamed: from (a descendant of) initWithCoder:. loadNibNamed: internally calls initWithCoder:. If you want to override the storyboard coder, and always load your xib implementation, I suggest the following technique. Add a property to your view class, and in the xib file, set it to a predetermined value (in User Defined Runtime Attributes). Now, after calling [super initWithCoder:aDecoder]; check the value of the property. If it is the predetermined value, do not call [self initializeSubviews];.

So, something like this:

-(instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];

if (self && self._xibProperty != 666)
{
//We are in the storyboard code path. Initialize from the xib.
self = [self initializeSubviews];

//Here, you can load properties that you wish to expose to the user to set in a storyboard; e.g.:
//self.backgroundColor = [aDecoder decodeObjectOfClass:[UIColor class] forKey:@"backgroundColor"];
}

return self;
}

-(instancetype)initializeSubviews {
id view = [[[NSBundle mainBundle] loadNibNamed:NSStringFromClass([self class]) owner:self options:nil] firstObject];

return view;
}


Related Topics



Leave a reply



Submit