What is the syntax for editing a label's constraints/position in swift? - swift

I want to set up a conditional that will change the location of a particular label in the view in swift. I figure I will put the change of the label's position in the viewDidLoad(), but if I put in this modification to move the label's constraints based on the conditional, will it (upon being reloaded) have the label in the position/constraint set manually on the storyboard? Or would I need to code that position back in?
if condition x{
//move label position
} else{
//keep the position set in storyboard, even upon reload
}
Is this possible?

///I have created the button & label on storyboard. And changing the position of label when button is clicked. I have added the constraint to the label on storyboard & created the outlet of top constraint.
var flag = true
#IBOutlet weak var UiLblConstraintTop: NSLayoutConstraint!
#IBAction func ChangePositionOfLabel(sender: UIButton) {
if flag{
self.UiLblConstraintTop.constant = 300
}
else{
self.UiLblConstraintTop.constant = 50
}
flag = !flag
self.view.layoutIfNeeded()
}

Related

Pushing UIViews up for UIKeyboard

I've added a willShow and willHide observer for the keyboard and am trying to push up the bottom UITextView up to adjust to the UIKeyboard showing. However, my keyboard is getting pushed farther up than just the keyboard frame height. How do I constrain the UITextView bottom anchor to the top of the keyboard?
// Observer method
#objc func handleKeyboardNotification(_ notification: NSNotification) {
if let userInfo = notification.userInfo {
let keyboardFrame = (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as AnyObject).cgRectValue
let isKeyboardShowing = (notification.name == UIResponder.keyboardWillShowNotification)
// Push views up if keyboard is showing, otherwise set constant back to 0
messageInputBottomAnchor?.constant = isKeyboardShowing ? -(keyboardFrame?.height)! : 0
UIView.animate(withDuration: 0.5) {
self.view.layoutIfNeeded()
}
}
}
What I did was
I created 2 different constraints on the UITextView, one to the superview and one to the safearea.
Connect both of those constraints over to the view controller and make sure that they are not weak references.
In viewDidLoad, make sure that the safearea constraint is active and the superview constraint isn't.
In your listeners when the keyboard comes up, switch the isActive fields of the constraints so now the superview one is active and safearea is inactive.
In the listener when it's going to resign, switch them back.
The reason for needing to make sure that the references aren't weak is because when you set the isActive field to false, it'll actually remove it and if you try and reference the constraint later, you'll find yourself trying to access a member of a nil object.
I left my UITextView constrained to the safeAreaLayoutGuide bottom but I added a CGFloat to represent the padding at the bottom of the screen. It defaulted as 0 but if iOS 11 was available (to account for the iPhone X and it's bottom padding), I set the CGFloat to UIApplication.shared.keyWindow!.safeAreaInsets.bottom. Then, when I moved the UITextView up or down according to the UIKeyboard, I subtracted the size of the CGFloat.
//Global var
var safeAreaBottom: CGFloat = 0.0
// Verify screen bottom in viewDidLoad
if #available(iOS 11, *) {
safeAreaBottom = UIApplication.shared.keyWindow!.safeAreaInsets.bottom
}
// Push views up if keyboard is showing, otherwise set constant back to 0. Subtract safeAreaBottom if iOS 11 is available to compensate for the bottom padding
textViewBottomAnchorToSafeArea?.constant = isKeyboardShowing ? -((keyboardFrame?.height)! - safeAreaBottom) : 0

how to hide textfield and auto layout the constraint in swift

so i have a segmented control in my project.I want to hide and auto layout my button.But the problem if i just hide the textfields and labels the button under my segmented control still not moving.So there is a space between my segmented control and next button.I want to move my next button up if i click no on my segmented control.
-if i click yes on segmented control
The next button under my segmented control will constraint my textfield and show all textfields and labels under my segmented control
-if i click no on segmented control
The next button under my segmented control will constraint to my segmented control and hide all textfields and labels under my segmented control
thanks for all the answers
the image
A quick example of how you could change the position of the button depending on the segment switch.
Below image shows dragging the auto layout height between Segment switch and button
Below Image shows using outlet and type needs to be NSLayoutConstraint
In your ViewController.Swift the code should look something like below.
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var switchControl: UISegmentedControl!
#IBOutlet weak var heighConstraint: NSLayoutConstraint!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
#IBAction func switchPressed(_ sender: Any) {
switch switchControl.selectedSegmentIndex
{
case 0:
// here you can see the constant is being set, this will determine the
// position of your button. You will need to set the correct position.
heighConstraint.constant = 150
case 1:
heighConstraint.constant = 200
default:
break;
}
}
}
Hope this answer helps.

Dragging NSSplitView divider does not resize views

I'm working with Cocoa and I create my views in code (no IB) and I'm hitting an issue with NSSplitView.
I have a NSSplitView that I configure in the following way in my view controller, in Swift:
override func viewDidLoad() {
super.viewDidLoad()
let splitView = NSSplitView()
splitView.isVertical = true
splitView.addArrangedSubview(self.createLeftPanel())
splitView.addArrangedSubview(self.createRightPanel())
splitView.adjustSubviews()
self.view.addSubview(splitView)
...
}
The resulting view shows the two subviews and the divider for the NSSplitView, and one view is wider than the other. When I drag the diver to change the width, as soon as I release the mouse, the divider goes back to its original position, as if pulled back by a "spring".
I can't resize the two subviews; the right one always keeps a fixed size. However, nowhere in the code I fix the width of that subview, or any of its content, to a constant.
What I would like to achieve instead is that the right view size is not fixed, and that if I drag the divider at halfway through, the subviews will resize accordingly and end up with the same width.
This is a screen recording of the problem:
Edit: here is how I set the constraints. I'm using Carthography, because otherwise setting constraints in code is extremely verbose beyond the most simple cases.
private func createLeftPanel() -> NSView {
let view = NSView()
let table = self.createTable()
view.addSubview(table)
constrain(view, table) { view, table in // Cartography magic.
table.edges == view.edges // this just constraints table.trailing to
// view.trailing, table.top to view.top, etc.
}
return view
}
private func createRightPanel() -> NSView {
let view = NSView()
let label = NSTextField(labelWithString: "Name of item")
view.addSubview(label)
constrain(view, label) { view, label in
label.edges == view.edges
}
return view
}

(swift) update a number to label will make the view get back to original position

demo image
When I update a number to label will make the view get back to original position.
class ViewController: UIViewController {
#IBOutlet weak var label: UILabel!
#IBOutlet var aview: UIView!
var number = 0
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func plus(sender: UIButton) {
number++
label.text = "number:\(number)"
}
#IBAction func move(sender: AnyObject) {
aview.frame.origin.y -= 20
}
}
I couldn't find the answer on web, please help me to fix this problem.Thank you very much!
Because your xib or Storyboard you set use Autolayout:
So if you don't set constrain system will auto generate it. When you change frame by set frame it effect but when you access to it. It will auto back to old position.
if you don't want it happen. You set in viewDidLoad:
self.view.translatesAutoresizingMaskIntoConstraints = false
Issue is probably related to a constraint reloading when the label reloads.
Instead of setting aview.frame.origin.y -= 20 you should make an outlet to the constraint holding the y position of your aView and then update the constant of that constraint outlet instead.

UILabel Swift/Storyboard returns nil

I created a navigation controller with a view controller inside, containing a label. This label should be changed, when the view controller is loaded on tapping a button.
class ViewController: UIViewController {
#IBOutlet weak var btnEmergency: UIButton!
override func viewWillAppear(animated: Bool) {
self.btnEmergency.backgroundColor = UIColor.redColor();
}
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func btnEmergencyTapped(sender: AnyObject) {
let emergencyViewController = storyboard?.instantiateViewControllerWithIdentifier("EmergencyViewController") as! EmergencyViewController
emergencyViewController.emergencyLabel?.text = "Notruf"
navigationController?.pushViewController(emergencyViewController, animated: true)
}
}
But the label text does not change when loaded. I am relatively new to SWIFT so I try to learn my ropes at the moment using optionals. So I guess the reason is, that the label is not yet instantiated when the view is being loaded on pressing the button. Therefore the default text is being shown and not the text I want to have appear on screen.
I am a little bit stuck at the moment, how to correctly change the label text, when this is an optional. So I guess I cannot expect the label to be there, when I call it. But how do I handle this correctly?
Instead of this, the correct way is to set a property of your emergencyViewController.
In your emergencyViewController viewDidLoad set your label text according to the property set previously.
Anything that you do between initialize of a viewController to viewDidLoad will not take effect.