I want to use a view throughout multiple viewcontrollers in a storyboard. Thus, I thought about designing the view in an external xib so changes are reflected in every viewcontroller. But how can one load a view from a external xib in a storyboard and is it even possible? If thats not the case, what other alternatives are availble to suit the situation abouve?
相关问题
- Core Data lightweight migration crashes after App
- How can I implement password recovery in an iPhone
- State preservation and restoration strategies with
- “Zero out” sensitive String data in Swift
- Get the NSRange for the visible text after scroll
相关文章
- 现在使用swift开发ios应用好还是swift?
- UITableView dragging distance with UIRefreshContro
- TCC __TCCAccessRequest_block_invoke
- Where does a host app handle NSExtensionContext#co
- Swift - hide pickerView after value selected
- How do you detect key up / key down events from a
- “Storyboard.storyboard” could not be opened
- didBeginContact:(SKPhysicsContact *)contact not in
Assuming that you've created an xib that you want to use:
1) Create a custom subclass of UIView (you can go to File -> New -> File... -> Cocoa Touch Class. Make sure "Subclass of:" is "UIView").
2) Add a view that's based on the xib as a subview to this view at initialization.
In Obj-C
In Swift 2
In Swift 3
3) Wherever you want to use it in your storyboard, add a UIView as you normally would, select the newly added view, go to the Identity Inspector (the third icon on the upper right that looks like a rectangle with lines in it), and enter your subclass's name in as the "Class" under "Custom Class".
For a while Christopher Swasey's approach was the best approach I had found. I asked a couple of the senior devs on my team about it and one of them had the perfect solution! It satisfies every one of the concerns that Christopher Swasey so eloquently addressed and it doesn't require boilerplate subclass code(my main concern with his approach). There is one gotcha, but other than that it is fairly intuitive and easy to implement.
MyCustomClass.swift
MyCustomClass.xib
File's Owner
of the .xib file to be your custom class (MyCustomClass
)class
value (under theidentity Inspector
) for your custom view in the .xib file blank. So your custom view will have no specified class, but it will have a specified File's Owner.Assistant Editor
.Connections Inspector
you will notice that your Referencing Outlets do not reference your custom class (i.e.MyCustomClass
), but rather referenceFile's Owner
. SinceFile's Owner
is specified to be your custom class, the outlets will hook up and work propery.NibLoadable
protocol referenced below..swift
file name is different from your.xib
file name, then set thenibName
property to be the name of your.xib
file.required init?(coder aDecoder: NSCoder)
andoverride init(frame: CGRect)
to callsetupFromNib()
like the example below.MyCustomClass
).Here is the protocol you will want to reference:
And here is an example of
MyCustomClass
that implements the protocol (with the .xib file being namedMyCustomClass.xib
):NOTE: If you miss the Gotcha and set the
class
value inside your .xib file to be your custom class, then it will not draw in the storyboard and you will get aEXC_BAD_ACCESS
error when you run the app because it gets stuck in an infinite loop of trying to initialize the class from the nib using theinit?(coder aDecoder: NSCoder)
method which then callsSelf.nib.instantiate
and calls theinit
again.I think about
alternative
for usingXIB views
to be usingView Controller
in separate storyboard.Then in main storyboard in place of custom view use
container view
withEmbed Segue
and haveStoryboardReference
to this custom view controller which view should be placed inside other view in main storyboard.Then we can set up delegation and communication between this embed ViewController and main view controller through prepare for segue. This approach is different then displaying UIView, but much simpler and more efficiently (from programming perspective) can be utilised to achieve the same goal, i.e. have reusable custom view that is visible in main storyboard
The additional advantage is that you can implement you logic in CustomViewController class and there set up all delegation and view preparation without creating separate (harder to find in project) controller classes, and without placing boilerplate code in main UIViewController using Component. I think this is good for reusable components ex. Music Player component (widget like) that is embeddable in other views.
This solution can be used even if your class does not have the same name as the XIB. For example, if you have a base view controller class controllerA which has a XIB name controllerA.xib and you subclassed this with controllerB and want to create an instance of controllerB in a storyboard, then you can:
*
My full example is here, but I will provide a summary below.
Layout
Add a .swift and .xib file each with the same name to your project. The .xib file contains your custom view layout (using auto layout constraints preferably).
Make the swift file the xib file's owner.
Code
Add the following code to the .swift file and hook up the outlets and actions from the .xib file.
Use it
Use your custom view anywhere in your storyboard. Just add a
UIView
and set the class name to your custom class name.Best solution currently is to just use a custom view controller with its view defined in a xib, and simply delete the "view" property that Xcode creates inside the storyboard when adding the view controller to it (don't forget to set the name of the custom class though).
This will make the runtime automatically look for the xib and load it. You can use this trick for any kind of container views, or content view.