I have a Swift app which sets a UIImageView to the size of a portion of the screen (set with autoconstraints to the margins and controls above it), and I use the height and width values of the ImageView to create 3 additional UIImageViews programmatically and position them on top of the original image. I am constructing a podium and place three images on top of the podium in appropriate positions. I then calculate the height and width of each additional image by creating a constant: let conImageHeight = 0.4 * self.imgPodium.frame.height. However, I can't get a reliable height and width of the original image.
Initially I used self.imgPodium.bounds.height which worked great for the iPhone 6 simulator screen size, but when I tried running the app on an iPad simulator, it kept the iPhone size values. The image itself changed size but when I println() the height and width using bounds, I get the values of the iPhone image.
I then changed and used self.imgPodium.frame.height but this didn't change anything.
Is there a better way to get the height and width of a UIImageView (or any control for that matter) after it positions itself through autoconstraints?
Thanks.
Questions I've looked at already but didn't help:
Change UIImageView size and position programmatically in Swift
how to check screen size of iphone 4 and iphone 5 programmatically in swift
UIImageView Bounds, Frame
Cocoa: What's the difference between the frame and the bounds?
How to resize an UIImageView (swift)
In viewDidLoad the subviews have been loaded and initialized but not layed out yet. Therefore their frame property for example is not valid yet and may be the one that was set in Xcode when designing the UI in the first place - that however is not reliable. You should do custom layout in places where you can be sure the layout has already happened yet: e.g in viewWillLayoutSubviews or viewDidLayoutSubviews. Both methods will also get called when the layout somehow needs to change. In viewDidAppear the layout has been done yet and therefore you can do some layouting too. This code however will get not get called when the layout changes due to interface rotation for example. AND it will get called after a presented viewController gets dismissed again. (not what you would want).
In both cases: do your setup of creating new imageViews in viewDidLoad and do the layout in viewWillLayoutSubviews or viewDidLayoutSubviews!
Related
I use two buttons in a camera app to track the zoom of said camera. My goal is to reduce the height & width of 1x if 2x is selected and vice-versa but it doesn't seem to work.
I tried button.frame.size.height = 8 button.frame.size.width = 8 and the height & width always remain the same. I even tried 500 to see if it would make a difference and it didn't.
I also tried button.size(CGFloat) to no avail...
I should probably mention that those buttons are nested in a StackView and the app is built on Storyboards. Also, the app is designed to be used on iOS 13+.
Thanks in advance!
UIStackView is using Auto Layout for arranging its subviews. Therefore, direct modifications of the button's frame will have no effect because Auto Layout will anyway recalculate all frames according to the active constraints on the next layout pass.
Since you're using a storyboard, here's how to solve it:
Open the storyboard, select your button and create a width and a height constraint for it.
Create IBOutlets for each of these constraints in your view controller. For the sake of the example let's say you name it buttonWidthConstraint and buttonHeightConstraint.
Whenever you want to change the size of the button, do this:
buttonWidthConstraint.constant = 8
buttonHeightConstraint.constant = 8
I have a dynamic UIView based on the height of a superView by using a multiplier (in my case 0.125 the height of the superview).
For any reason, when I want to recover the value of the view:
let rangeSliderHeight = playerView.bounds.size.height * 0.5
I get the same size with my iPhone 5 and my iPad, even though visually, on iPad is much more big than iPhone.
There's no autolayout option to define custom rules for iPads or iPhones for this case, since the library I use builds the element from code.
Is there any posibility to get the real size of the UIView depending of the device?
Call playerView.bounds.size.height in viewDidLayoutSubviews() instead of viewDidLoad(). At that point the views will have been laid out and you can retrieve the actual size.
i'm creating an app for iPhone and iPad. and now i would want to retrieve the size of an UIImageView on different phone screen. I have tried with following code:
print("width \(BubbleBackground.frame.size.width)")
print("height \(BubbleBackground.frame.size.height)")
print("width1 \(BubbleBackground.bounds.size.width)")
print("height1 \(BubbleBackground.bounds.size.height)")
print("width2\(BubbleBackground.image!.size.width)")
print("height2\(BubbleBackground.image!.size.height)")
I have tried with the code above, but yet they return me a constant value no matter it is running in iPhone 5, iPhone 6, iPhone 6 plus or iPad. Does anyone have an idea how can i get the image size when it is running on different device?
You have to have some constraints to change the imageView frame according to the screen size. Then you can use .layoutIfNeeded() on the UIImageView (BubbleBackground.layoutIfNeeded()) to get its runtime size.
make sure you do this in viewWillAppear or viewDidLayoutSubviews or anytime after these events.
Your image will be the same size on all devices unless you have set constraints on the image that cause it to resize to fit the current screen size.
Constraints are most often added using Xcode's Interface Builder but can also be added programatically.
Adding constraints using the Interface Builder
https://developer.apple.com/library/prerelease/content/documentation/UserExperience/Conceptual/AutolayoutPG/WorkingwithConstraintsinInterfaceBuidler.html#//apple_ref/doc/uid/TP40010853-CH10-SW1
Adding Constraints Programatically https://developer.apple.com/library/prerelease/content/documentation/UserExperience/Conceptual/AutolayoutPG/ProgrammaticallyCreatingConstraints.html
i have noticed that an UiImageView that's set to take full width is not given its correct width before viewDidAppear.
This is a bit problmatic for me because:
I load in a custom logo graphic that can have any high/width
This means that to keep scale (and full width) I set a height constraint to match width/height proportions in the .png file
However, I can not get true image width before viewDidAppear - nor viewWillAppear
Am I missing a stage / tehcnique here (new to xcode/ios/swift) or will I have o maybe make my own calcluations and no rely on retrieving the width of an uiimageview?
keep in mind that viewDidLoad is called only when your view is loaded and not yet put on a superview, so you still don't know how is it's final frame, it has just the frame you defined in its xib file (if any)
but then you add it in a superview (in many way) and so (following its autoresizingMask) its frame size changes, and you can get them only in
viewDidAppear method
I've laid out a UIView in my UIViewController. Constrained its height and width, and centered it vertically and horizontally with constraints, but when I log its frame, it reports a location that seems appropriate to the full sizeClass, but not the size of the screen I'm looking at.
For example the default size class UIViewController has a width of 600px, and in that size, my UIView is 150px from the left edge. When I check this distance from the left edge while running in the iphone5 simulator, it still reports 150px.
The weird thing about all of this, is that the UIView itself still appears in the expected (adjusted for screen-size) location.
For posterity: the problem I was having -- getting incorrect values when printing the frame of a view -- was caused by accessing that frame during ViewDidLoad. At this point in the ViewController lifecycle all views may have not been laid out.
Therefore, it is safest to access a UIView property/outlet only after ViewDidLayoutSubviews has been called.
I mean, it's right there in the name of the method: "Your views have been laid out... now do stuff with them."