xSHERU xSHERU - 25 days ago 24
Swift Question

Custom View size in iOS not dynamic

I just have started my first app on iOS a week ago. I have created a custom view to use it in my app using AppleDeveloperWebsite Custom Rating Control Tutorial.

Now I have chosen iPhone7 device in storyboard and I run this on iPhone 7 emulator it works perfectly but when I run it on iPhone 5 emulator (size of screen changes) my custom views extend beyond the screen. My all other controls sizes resize as I set constraints but only my custom view sizes get messed up.

Please Help

import UIKit

@IBDesignable class xRadioButtonView: UIView {
var button: UIButton!
var label: UILabel!

@IBInspectable var text: String? {
didSet{
label.text = text
}
}

//Properties
var isSelected = 0

//Initialization
override init(frame: CGRect){
super.init(frame: frame)
addSubviews()
}

required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)!
addSubviews()
}

func addSubviews() {
self.backgroundColor = UIColor.white

let xWidth = bounds.size.width
let xHeight = bounds.size.height

let tap = UITapGestureRecognizer(target: self, action: #selector(xRadioButtonView.radioButtonTextTapped))

button = UIButton(frame: CGRect(x: 1, y: 1, width: xWidth - 2, height: xHeight - 4))
button.backgroundColor = UIColor.white
button.addTarget(self, action: #selector(xRadioButtonView.radioButtonTapped(button:)), for: .touchDown)

addSubview(button)

label = UILabel(frame: CGRect(x: 1, y: 1, width: xWidth - 2, height: xHeight - 2))
label.textColor = UIColor.init(hex: "#D5D5D5")
//label.font = UIFont.init(name: label.font.fontName, size: 25)
//label.font = label.font.withSize(25)
label.font = UIFont.boldSystemFont(ofSize: 25)
label.textAlignment = NSTextAlignment.center
label.isUserInteractionEnabled = true
label.addGestureRecognizer(tap)

addSubview(label)
}

override func layoutSubviews() {
// Set the button's width and height to a square the size of the frame's height.

}

override func prepareForInterfaceBuilder() {
super.prepareForInterfaceBuilder()
label.text = "xRBV"
}

func radioButtonTapped(button: UIButton) {
if isSelected == 0 {
isSelected = 1
self.backgroundColor = UIColor.init(hex: "#00BFA5")
label.textColor = UIColor.init(hex: "#00BFA5")
} else {
isSelected = 0
self.backgroundColor = UIColor.white
label.textColor = UIColor.init(hex: "#D5D5D5")
}
}

func radioButtonTextTapped(sender: UITapGestureRecognizer){
if isSelected == 0 {
isSelected = 1
self.backgroundColor = UIColor.init(hex: "#00BFA5")
label.textColor = UIColor.init(hex: "#00BFA5")
} else {
isSelected = 0
self.backgroundColor = UIColor.white
label.textColor = UIColor.init(hex: "#D5D5D5")
}
}
}



As you can see PG button should finish where green color finishes but white color button is extended beyond the screen

Answer

You either need to set the frame in layoutSubViews or you need to implement autolayout in code:

    button = UIButton(frame: CGRect(x: 1, y: 1, width: xWidth - 2, height: xHeight - 4))
    button.backgroundColor = UIColor.white
    button.addTarget(self, action: #selector(xRadioButtonView.radioButtonTapped(button:)), for: .touchDown)
    addSubview(button)
    button.translatesAutoresizingMaskIntoConstraints = false
    let atrributes: [NSLayoutAttribute] = [.top, .bottom, .leading, .trailing]
    NSLayoutConstraint.activate(atrributes.map { NSLayoutConstraint(item: button, attribute: $0, relatedBy: .equal, toItem: button.superview, attribute: $0, multiplier: 1, constant: 1) })

The example uses the old way because your constraints are uniform, but if you have something more complicated its often simpler to use NSLayoutAnchor as of iOS 9.

Comments