Search code examples
iosswiftuiviewios9init

swift UIView subclass with optional SubViews from passed value


I have a UIView subclass that has a UILabel for title, a button and another subview that will change based on a passed value when the view is used in another viewcontroller.

class CustomView: UIView {

    enum PickerType {
        case pikerView
        case datePicker
    }

    private var dialogView:   UIView!
    private var titleLabel:   UILabel!
    private var pickerView:   UIPickerView!
    private var datePicker:   UIDatePicker!

    private var pickerType: PickerType!

    init() {
    super.init(frame: CGRectMake(0, 0, UIScreen.mainScreen().bounds.size.width, UIScreen.mainScreen().bounds.size.height))
    setupView()
}

required init(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

func setupView() {
    self.dialogView = createContainerView()

    self.dialogView.layer.shouldRasterize = true
    self.dialogView.layer.rasterizationScale = UIScreen.mainScreen().scale

    self.layer.shouldRasterize = true
    self.layer.rasterizationScale = UIScreen.mainScreen().scale

    self.dialogView.layer.opacity = 0.5
    self.dialogView.layer.transform = CATransform3DMakeScale(1.3, 1.3, 1)

    self.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0)

    self.addSubview(self.dialogView)
}

private func createContainerView() -> UIView {
    let screenSize = getScreenSize()
    let dialogSize = CGSizeMake(screenSize.width, 300)

    // For the black background
    self.frame = CGRectMake(0, 0, screenSize.width, screenSize.height)

    let dialogContainer = UIView(frame: CGRectMake(0, screenSize.height - dialogSize.height, dialogSize.width, dialogSize.height))

    //Title
    self.titleLabel = UILabel(frame: CGRectMake(10, 10, dialogSize.width - 20, 30))
    self.titleLabel.textAlignment = NSTextAlignment.Center
    self.titleLabel.font = UIFont.boldSystemFontOfSize(17)
    dialogContainer.addSubview(self.titleLabel)

    //Add the PickerView
    addPickerView(dialogContainer)

    return dialogContainer
}

/**Add the appropriate view based on pickerType*/
private func addPickerView(dialogContainer: UIView) {
    let screenSize = countScreenSize()
    let dialogSize = CGSizeMake(screenSize.width, 250)

    if pickerType == PickerType.pikerView {
        self.pickerView = UIPickerView(frame: CGRectMake(10, 30, 0, 0))
        self.pickerView.autoresizingMask = UIViewAutoresizing.FlexibleRightMargin
        self.pickerView.frame.size.width = dialogSize.width - 20
        dialogContainer.addSubview(self.pickerView)
    } else if pickerType == PickerType.datePicker {
        self.datePicker = UIDatePicker(frame: CGRectMake(10, 30, 0, 0))
        self.datePicker.autoresizingMask = UIViewAutoresizing.FlexibleRightMargin
        self.datePicker.frame.size.width = dialogSize.width - 20
        dialogContainer.addSubview(self.datePicker)
    }
}

func showPickerView(title: String) {
    self.pickerType = PickerType.pikerView
    self.titleLabel.text = title
}

func showDatePicker(title: String) {
    self.pickerType = PickerType.datePicker
    self.titleLabel.text = title
}
}

The idea is, if CustomView().showPickerView is called, then the pickerType variable will be assigned the appropriate value and UIPickerView is loaded. and if CustomView().showDatePicker is called, the UIDatePicker is loaded.

My problem is, the addPickerView is called before either of showPickerView() or showDatePicker() is called.

How do I pass the value for pickerType before the view is initialized?


Solution

  • I've got it to work by changing the initializer as:

    init(picker: PickerType) {
        super.init(frame: CGRectMake(0, 0, UIScreen.mainScreen().bounds.size.width, UIScreen.mainScreen().bounds.size.height))
    
        self.pickerType = picker
        setupView()
    }
    

    and taking out the PickerType enum outside of the CustomView.

    Now I can use the custom view as:

    CustomView(picker: PickerType.datePicker).showDatePicker("Select date")
    CustomView(picker: PickerType.pickerView).showPickerView("Select data")
    

    But I'd love suggestions if there is a more efficient way of implementing this.