How do I write a custom init for a UIView subclass in Swift?

前端 未结 5 1831
野的像风
野的像风 2021-01-29 20:48

Say I want to init a UIView subclass with a String and an Int.

How would I do this in Swift if I\'m just subclassing

相关标签:
5条回答
  • 2021-01-29 20:50

    Here is how I do a Subview on iOS in Swift -

    class CustomSubview : UIView {
    
        init() {
            super.init(frame: UIScreen.mainScreen().bounds);
    
            let windowHeight : CGFloat = 150;
            let windowWidth  : CGFloat = 360;
    
            self.backgroundColor = UIColor.whiteColor();
            self.frame = CGRectMake(0, 0, windowWidth, windowHeight);
            self.center = CGPoint(x: UIScreen.mainScreen().bounds.width/2, y: 375);
    
            //for debug validation
            self.backgroundColor = UIColor.grayColor();
            print("My Custom Init");
    
            return;
        }
    
        required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented"); }
    }
    
    0 讨论(0)
  • 2021-01-29 20:51

    I create a common init for the designated and required. For convenience inits I delegate to init(frame:) with frame of zero.

    Having zero frame is not a problem because typically the view is inside a ViewController's view; your custom view will get a good, safe chance to layout its subviews when its superview calls layoutSubviews() or updateConstraints(). These two functions are called by the system recursively throughout the view hierarchy. You can use either updateContstraints() or layoutSubviews(). updateContstraints() is called first, then layoutSubviews(). In updateConstraints() make sure to call super last. In layoutSubviews(), call super first.

    Here's what I do:

    @IBDesignable
    class MyView: UIView {
    
          convenience init(args: Whatever) {
              self.init(frame: CGRect.zero)
              //assign custom vars
          }
    
          override init(frame: CGRect) {
               super.init(frame: frame)
               commonInit()
          }
    
          required init?(coder aDecoder: NSCoder) {
               super.init(coder: aDecoder)
               commonInit()
          }
    
          override func prepareForInterfaceBuilder() {
               super.prepareForInterfaceBuilder()
               commonInit()
          }
    
          private func commonInit() {
               //custom initialization
          }
    
          override func updateConstraints() {
               //set subview constraints here
               super.updateConstraints()
          }
    
          override func layoutSubviews() {
               super.layoutSubviews()
               //manually set subview frames here
          }
    
    }
    
    0 讨论(0)
  • 2021-01-29 21:00

    The init(frame:) version is the default initializer. You must call it only after initializing your instance variables. If this view is being reconstituted from a Nib then your custom initializer will not be called, and instead the init?(coder:) version will be called. Since Swift now requires an implementation of the required init?(coder:), I have updated the example below and changed the let variable declarations to var and optional. In this case, you would initialize them in awakeFromNib() or at some later time.

    class TestView : UIView {
        var s: String?
        var i: Int?
        init(s: String, i: Int) {
            self.s = s
            self.i = i
            super.init(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
        }
    
        required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
        }
    }
    
    0 讨论(0)
  • 2021-01-29 21:12

    Swift 5 Solution

    You can try out this implementation for running Swift 5 on XCode 11

    
    class CustomView: UIView {
    
        var customParam: customType
        
        var container = UIView()
        
        required init(customParamArg: customType) {
            self.customParam = customParamArg
            super.init(frame: .zero)
            // Setting up the view can be done here
            setupView()
        }
    
        required init?(coder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
        
    
        func setupView() {
            // Can do the setup of the view, including adding subviews
    
            setupConstraints()
        }
        
        func setupConstraints() {
            // setup custom constraints as you wish
        }
        
        
    }
    
    
    
    0 讨论(0)
  • 2021-01-29 21:16

    Here is how I do it on iOS 9 in Swift -

    import UIKit
    
    class CustomView : UIView {
    
        init() {
            super.init(frame: UIScreen.mainScreen().bounds);
    
            //for debug validation
            self.backgroundColor = UIColor.blueColor();
            print("My Custom Init");
    
            return;
        }
    
        required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented"); }
    }
    

    Here is a full project with example:

    • UIView Example Project (with SubView example)
    0 讨论(0)
提交回复
热议问题