Why do my UIImageView coordinates change when I update label value? - ios

I want to move my UIImageView when a certain button is clicked. I have this code:
#IBOutlet weak var counter: UILabel!
#IBOutlet weak var indexCrow: UIImageView!
var crow = 0
#IBAction func plusButton(sender: UIButton) { // Plus Button
indexCrow.frame = CGRect(x: indexCrow.frame.origin.x + 20, y: indexCrow.frame.origin.y, width: indexCrow.frame.size.width, height: indexCrow.frame.size.height)
crow++
counter.text = String(crow)
}
If I remove the line counter.text = String(crow), my image view moves correctly, but my label does not update. If I write counter.text = String(crow) my label updates, but my image view does not move.
What I do wrong?

AutoLayout is running when you update the label and placing your image back to where it started. You have several options to deal with this. Choose one:
Turn off AutoLayout. Most don't choose this option because they want their layouts to work on multiple devices.
Create your imageView programmatically instead of in Interface Builder. If you do this, it won't be subject to AutoLayout and you can move it freely.
Place your imageView using AutoLayout constraints. Add IBOutlets to those constraints and update the constant values in code instead of modifying the frame.
When plusButton is called, store the new frame for your imageView in a property in your ViewController, and then put that frame in place in an override of viewDidLayoutSubviews which happens after AutoLayout runs.

Related

Question about changing height of UIView when button is pressed in Swift

I am making a function that the height of a UIView increases and decreases when a button is pressed.
When the height of the UIView was reduced, the value created a layout in the storyboard, When the height of the UIView is increased, the value will be the height of the UITextView.
The picture above is before the UIView is stretched. Press the button at the bottom of the photo to stretch the UIView
The picture above is after the UIView is stretched. If you press the button at the bottom of the picture above, the UIView will shrink again.
The first thing I am curious about is the code to make the height of the UIView increase.
#IBOutlet weak var bookInfoView: UIView!
#IBOutlet weak var bookInfoVieweBtn: UIButton!
#IBOutlet weak var bookInfoTextView: UITextView!
#IBAction func bookInfoViewBtnTapped(_ sender: Any) {
print("##bookInfoViewBtnTapped!")
let f = bookInfoView.frame
let textView = bookInfoTextView.frame
bookInfoView.frame = CGRect(x: f.origin.x, y: f.origin.y, width: f.width, height: textView.height)
}
If you press the button using the code above, it does nothing. What should I do?
1.Set some default value for the height of your the view your are trying to expand. Then if you are using StoryBoard make an IBOutlet to your ViewConroller, and remove the weak reference (that's because we are going to deactivate the height anchor and if it is weak and you deactivate it, the ARC will dealocate it. If your are going for it programatically just store the height anchor in a local variable. So it should like something like this:
#IBOutlet var yourViewHeightAnchor: NSLayoutConstraint!
2. Add a target to your button or if your using StoryBoard or Xib drag a IBAction to you ViewController. When the button is clicked, your only job is to deactive/active the height anchor. ( The activation will serve for collapse)
#IBAction func expandClicked(_ sender: Any) {
yourViewHeightAnchor.isActive.toggle()
}
If you wish to use some animation for expanding/collapsing, your expandClicked function should look something like this:
#IBAction func expandClicked(_ sender: Any) {
UIView.animate(withDuration: 0.6, animations: {
self.yourViewHeightAnchor.isActive.toggle()
self.view.layoutIfNeeded()
})
}
Follow below steps:-
Define height constraint in your storyboard.
create IBOutlet of height constraint
Then on button press, increase/decresse your height of textview like:-
textViewHeightConstant.constant = someValue

How to create an expandable text field/label in swift?

I need to figure out how to program something like this:
The text expands as the user clicks the down button and fold back to the short version after clicking up. Are there any libraries I could study? I am a beginner in programming and just need advice on how to approach this task, what guides to study and so on.
All you have to do is initially set the UILabel to have a numberOfLines of lets say 7 and line break mode to be .byTruncatingTail.
Then on button click simply change the numberOfLines to 0 and line break mode to be .byWordWrapping. Then when you wish to hide the text, just press the button and set the UILabel to its initial values.
To solve this issue read about AutoLayout. This is small example how it is possible to do.
This is coding part. This class contain IBOutlet for the height of the UITextView and button action.
class ViewController: UIViewController {
let defaultHeight = 128
let expectedHeight = 600
var state: Bool = false
#IBOutlet weak var height: NSLayoutConstraint!
#IBAction func showAction(_ sender: Any) {
UIView.animate(withDuration: 0.3, animations: {
self.state = !self.state
self.height.constant = CGFloat(self.state ? self.expectedHeight: self.defaultHeight)
self.view.layoutIfNeeded()
})
}
}
This is from storyboard.
You can set an height constraint for your UILabel, and on the tap button event change the constraint constant to the contentsize of your label.
After your can animate it with
UIView.animate(duration)

How do I display a UIImageView via a Switch on state? Then...how do I add constraints to the UIImageView to either center it or such?

I am trying to have a UIImageView (centered horizontally in the viewController) with a UISwitch inside of it.
When the UIswitch is turned to the ON position - a second UIImageView should appear to the left of the original UIImageView, while the constraints should make it so that both UIImageViews are centered horizontally.
thanks in advance
There are many ways to do this, but the easiest is to simply use a centered horizontal UIStackView that contains only a single imageView. When the switch is flipped add the second imageView to the stackView by calling insertArrangedSubview(:at:) and the stackView will take care of maintaining the centering and any requested spacing. Similarly when the switch is off just call removeArrangedSubview(:) and everything goes back into place.
If you are not on iOS 9 and don't have UIStackView you can just drag an IBOutlet to the view that you want to move's centerX constraint and add to its .constant property and animate layoutIfNeeded to have it slide to the right.
class ViewController: UIViewController{
#IBOutlet weak var imageView: UIImageView!
#IBOutlet weak var imageViewCenterXConstraint: NSLayoutConstraint!
let padding = CGFloat(10)
#IBAction func tapButton(_ sender: Any) {
imageViewCenterXConstraint.constant = imageView.frame.size.width / 2 + padding
UIView.animate(withDuration: 0.25) { self.view.layoutIfNeeded()}
}
}

storyboard dynamic auto layout issue

I have this situation :
When I tap on "add" button I reduce the pink view's(first view) height and I execute this code:
#IBOutlet weak var viewPink: UIView!
#IBAction func add(_ sender: AnyObject) {
viewPink.frame = CGRect(x: viewPink.frame.origin.x, y: viewPink.frame.origin.y, width: viewPink.frame.size.width, height: viewPink.frame.size.height - 50)
}
but I want that the last view remains to the same distance from the pink view , essentially you have to climb on why the pink view reduces its height , instead the second view remains where it was before.
Can you help me about it?
P.S I set the vertical spacing constraint between the two views but It doesn't work
You should add an Height constraint on your pink view, create an IBOutlet to this constraint in your ViewController, and set the "constant" property to change the height.
Example:
heightConstraint.constant = 150
This will change the height with Autolayout, you shouldn't change the height by setting a new frame because it doesn't use Autolayout.

NSLocalization + Storyboard using Swift

So this is very strange:
I created a small UIView in Storyboard, changed its color so we can see it.
I also created a button so I can make this view bigger.
What happens is it only works if I don't access NSLocalizedString. If I decomment the line it stops working.
Why is this?
class MasterViewController: UIViewController {
#IBOutlet weak var bar: UIView!
#IBOutlet weak var button: UIButton!
var integer : Int = 0
#IBAction func makeBarGrow(sender : AnyObject) {
self.integer++
//self.button.setTitle(NSLocalizedString("test \(integer)", comment : "test"), forState:UIControlState.Normal)
self.bar.frame = CGRectMake(self.bar.frame.origin.x,
self.bar.frame.origin.y,
self.bar.frame.size.width + 10,
self.bar.frame.size.height)
}
}
Thank you
When you set the label on your button, Auto Layout runs and sets the frame of your bar back to its initial value. When Auto Layout is enabled, you shouldn't adjust frame sizes. Instead, you should use size constraints like so:
Add an Auto Layout constraint on your bar that sets its width. To do this, select your bar view in Interface Builder and click the Auto Layout Pin icon |-[]-|, click the box next to Width, and set the constant to your desired initial value. Then click Add 1 Constraint at the bottom.
Add an IBOutlet to this constraint in your ViewController by Control dragging from the constraint in the Document Layout View to your code:
#IBOutlet weak var barWidth: NSLayoutConstraint!
In makeBarGrow, replace frame adjusting code with:
barWidth.constant += 10

Resources