How to embed a custom view xib in a storyboard scene?

前端 未结 11 549
生来不讨喜
生来不讨喜 2021-01-29 21:33

I\'m relatively new in the XCode/iOS world; I\'ve done some decent sized storyboard based apps, but I didn\'t ever cut me teeth on the whole nib/xib thing. I want to use the sam

11条回答
  •  再見小時候
    2021-01-29 22:18

    You need to implement awakeAfterUsingCoder: in your custom UIView subclass. This method allows you to exchange the decoded object (from the storyboard) with a different object (from your reusable xib), like so:

    - (id) awakeAfterUsingCoder: (NSCoder *) aDecoder
    {
        // without this check you'll end up with a recursive loop - we need to know that we were loaded from our view xib vs the storyboard.
        // set the view tag in the MyView xib to be -999 and anything else in the storyboard.
        if ( self.tag == -999 )
        {
            return self;
        }
    
        // make sure your custom view is the first object in the nib
        MyView* v = [[[UINib nibWithNibName: @"MyView" bundle: nil] instantiateWithOwner: nil options: nil] firstObject];
    
        // copy properties forward from the storyboard-decoded object (self)
        v.frame = self.frame;
        v.autoresizingMask = self.autoresizingMask;
        v.translatesAutoresizingMaskIntoConstraints = self.translatesAutoresizingMaskIntoConstraints;
        v.tag = self.tag;
    
        // copy any other attribtues you want to set in the storyboard
    
        // possibly copy any child constraints for width/height
    
        return v;
    }
    

    There's a pretty good writeup here discussing this technique and a few alternatives.

    Furthermore, if you add IB_DESIGNABLE to your @interface declaration, and provide an initWithFrame: method you can get design-time preview to work in IB (Xcode 6 required!):

    IB_DESIGNABLE @interface MyView : UIView
    @end
    
    @implementation MyView
    
    - (id) initWithFrame: (CGRect) frame
    {
        self = [[[UINib nibWithNibName: @"MyView"
                                bundle: [NSBundle bundleForClass: [MyView class]]]
    
                 instantiateWithOwner: nil
                 options: nil] firstObject];
    
        self.frame = frame;
    
        return self;
    }
    

提交回复
热议问题