Where to Get Frame Size of Custom Uiview in Its Subclass

Where to get frame size of custom UIView in its subclass

func viewWillAppear(_ animated: Bool)

This is called on the viewController after the view hierarchy is in place and the geometry is set up.

It is usually the best place to arrange geometry-dependent viewController code, and is called just before transition animations are run.

It is followed by a call to viewDidAppear which is called after transition animations have completed.

update

as you want to set this directly in a custom view (rather than in the viewController) the appropriate UIView function to override is layoutSubviews. Be sure to call super.layoutSubviews() in the override.

override func layoutSubviews() {
super.layoutSubviews()
//self.frame will be correct here
}

This will be called after the viewController's viewWillAppear and before viewDidAppear

update 2: collectionView cells
Collection view cells get their frame data from the collectionview's layout. When a cell needs to know it's geometry, you can override applyLayoutAttributes

func applyLayoutAttributes(_ layoutAttributes: UICollectionViewLayoutAttributes!)

One of the default layoutAttributes is the frame property. See also my comment below on how to extract the frame directly from collectionView.layout.

How to get frame from UIView subclass with AutoLayout

After battling around with it I've figured out what was happening.

layoutSubviews() is indeed the way to go;
It will calculate the frames of the view and it's direct subviews.

The problem here is that the UILabels are not subviews of the main UIView subclass, but rather are subviews of the main UIView's subview (effect view).

Your view hierarchy example:

--> TestView
--> EffectView
--> UILabel
--> UILabel
--> UILabel

As you can see, layoutSubviews() will give you the correct frames for TestView and EffectView since it's its direct subview, but won't give you the calculated frames from UILabels because they aren't direct subviews of TestView.

Getting size of UIView in init

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
}
}

How to get dimensions of a custom UIView added via storyboard in initWithCoder:?

Rather than set the subviews dimensions in the init function, set it relative to the custom view in the layoutSubviews method of the custom view. Doing it here will mean that the width of the subview will also always change to match the width of the custom view even if you change the dimensions of the custom view at any point after initialisation.

how do I set the size/position of a custom UIView for its placing within a custom UITableViewCell?

any views added as part of the tableViewCell subclass are positioned relative to the cells frame, ie x:0,y:0 for the subview origin, would be the top left corner of the tableCell.
Something like this should be enough to get you started.

CGRect frame =[self frame];
frame.size.height=20.0f;
frame.origin.x=(self.frame.size.height/2)-frame.size.height;
frame.origin.y=0.0f;
[subview setFrame:frame];


Related Topics



Leave a reply



Submit