I have made a custom subclass of UIView in my iOS application, and I am trying to get the computed sizes of the view in the view's init method, so I can use them when creating subviews to put inside the custom view.
The custom view is inside a stack view, which assigns my view 1/3 of the total (main view) height.
My init looks like this:
var mySubView: UIImageView
required init?(coder aDecoder: NSCoder) {
mySubView = UIImageView()
super.init(coder: aDecoder)
let viewWidth = Int(self.frame.size.width)
let viewHeight = Int(self.frame.size.height)
mySubView.frame = CGRect(x: 0, y: 0, width: viewWidth, height: viewHeight)
mySubView.backgroundColor = UIColor.cyan
self.addSubview(mySubView)
}
However, the heights and widths are not reported correctly. For instance, mySubView above only ends up filling about half of the total space of the custom view.
Any help would be greatly appreciated!
An object that manages the content for a rectangular area on the screen. Views are the fundamental building blocks of your app's user interface, and the UIView class defines the behaviors that are common to all views. A view object renders content within its bounds rectangle, and handles any interactions with that content.
Use the UIViewPropertyAnimator class to perform animations instead. class func animate(withDuration: TimeInterval, delay: TimeInterval, options: UIView.AnimationOptions, animations: () -> Void, completion: ( (Bool) -> Void)?) Animate changes to one or more views using the specified duration, delay, options, and completion handler.
A view object renders content within its bounds rectangle and handles any interactions with that content. The UIView class is a concrete class that you can instantiate and use to display a fixed background color. You can also subclass it to draw more sophisticated content.
Because UIView is a highly configurable class, there are also many ways to implement sophisticated view behaviors without overriding custom methods, which are discussed in the Alternatives to Subclassing section. In the meantime, the following list includes the methods you might consider overriding in your UIView subclasses:
The initializer is called too early in the lifecycle of the view to accurately do layout unless you know the exact dimensions in advance. Even so, it is idiomatically the wrong place to do it.
Try using the layoutSubviews
method as such:
class SubView: UIImageView {
var mySubView: UIImageView
required init?(coder aDecoder: NSCoder) {
mySubView = UIImageView()
mySubView.backgroundColor = UIColor.cyan
super.init(coder: aDecoder)
self.addSubview(mySubView)
}
override func layoutSubviews() {
mySubView.frame = self.bounds
super.layoutSubviews()
}
}
Now the subview bounds will be set properly at the start of each layout pass. It’s a cheap operation.
Also, the bounds
property of a UIView
is the frame
translated to the view’s internal coordinate space. This means that normally this is true: bounds = CGRect(x: 0, y: 0, width: frame.size.width, height: frame.size.height)
. I suggest reading the documentation on view layout.
Alternatively, you can ditch manual layout entirely and use AutoLayout to do this for you.
class SubView: UIImageView {
var mySubView: UIImageView
required init?(coder aDecoder: NSCoder) {
mySubView = UIImageView()
mySubView.backgroundColor = UIColor.cyan
super.init(coder: aDecoder)
self.addSubview(mySubView)
mySubView.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true
mySubView.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
mySubView.widthAnchor.constraint(equalTo: widthAnchor).isActive = true
mySubView.heightAnchor.constraint(equalTo: heightAnchor).isActive = true
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With