0

I have a scroller at the bottom of my view controller which contains buttons. Buttons are not always active, they change as the user adds them to his favourites. Which means I have to decide on the x position of the buttons programmatically.

What I have done is created outlets of all the buttons from the view controller in the storyboard to the script and I am attempting to access them like this (simplified code):

    var Items = [String : Bool] 
    @IBOutlet weak var item1: UIButton!

...

    if Items[item] == true {

        item1.isEnabled = true
        \\ here comes a line of code where i should position item1's x position but I haven't managed to find the right way
    }

The question is how to change the x position of UIButton programmatically, and are there better ways to handle the problem? I am using Xcode 8 and swift 3

EDIT :

Method for constraints:

    func activeConstraint(element: UIButton, constant: Int) {

        let widthConstraint100 = NSLayoutConstraint(item: element,
                                                           attribute:NSLayoutAttribute.width,
                                                 relatedBy:NSLayoutRelation.equal,
                                                 toItem:nil,
                                                 attribute:NSLayoutAttribute.notAnAttribute,
                                                 multiplier:1.0,
                                                 constant: 100)

        let widthConstraint0 = NSLayoutConstraint(item: element,
                                                    attribute:NSLayoutAttribute.width,
                                                    relatedBy:NSLayoutRelation.equal,
                                                    toItem:nil,
                                                    attribute:NSLayoutAttribute.notAnAttribute,
                                                    multiplier:1.0,
                                                    constant: 0)

        if constant == 0 {
            element.removeConstraint(widthConstraint100)
            element.addConstraint(widthConstraint0)
        } else {
            element.removeConstraint(widthConstraint0)
            element.addConstraint(widthConstraint100)
        }

        element.updateConstraints()
    }

Example of call to the function:

    if Items[item] == true {

        activeConstraint(element: item, constant: 100)
    } else {  

        activeConstraint(element: item, constant: 0)
    }

EDIT 2:

Although I have seen many questions here referring UIStackView (like this one), none of the solutions worked for me. I have an horizontal scroller at the bottom of the screen with many buttons that get activated or deactivated programmatically with their width constraint set to 0 or 100. Here is the final result that works in my case (XCode 8.0) :

Hierarchy: image

  1. UIScrollView HAS to have one element: View (lets call it Container View) that holds all the contents of the scroller. Container view needs to have 4 constraints - top, bottom, leading and trailing set towards superView (UIScrollView). (preferably all 4 set to 0). Also set vertical constraint to center horizontally from Container view to superView - UIScrollView.

  2. StackView holds all the buttons - it needs to have all 4 constraints (top, bottom, leading, trailing) set towards superView which is Container View.

  3. All buttons need to have their width constraint set to a constant of desire.

Community
  • 1
  • 1
Vodenjak
  • 806
  • 1
  • 13
  • 21
  • If I understand your problem right, I think you could anyway use auto-layout. Just assign to your buttons a width constraint, and setup outlets to these constraints. Then you can change the width constraint constant to 0 or the required width by code as required, and everything else should work automatically for all screen sizes. – Reinhard Männer Oct 20 '16 at 09:09
  • Thank you for the idea, I tried to make it work, however there are no buttons showing at all in the scroller this way. – Vodenjak Oct 25 '16 at 07:16
  • I just realized that you are using a scrollView. Here it is indeed a little more complicated to set the constraints right. [Here](https://www.natashatherobot.com/ios-autolayout-scrollview/) is a tutorial. Just try to place your buttons at full width accordingly. If they are all shown correctly, you can set their width via outlets to their width constraints as required. Good luck! – Reinhard Männer Oct 25 '16 at 07:24
  • I managed to do it according to your advice, however now I am having this problem: first three buttons that were initially on the screen work normally, but the ones that appear upon scrolling act like labels (non interactable). Do you think that setting width = 0 has anything to do with this? – Vodenjak Oct 31 '16 at 09:56
  • This is hard to say without code. Generally, if you have set up your buttons all the same way (with target and action, and enabled), and they are visible (before or after scroll-in), each button should trigger its action when pressed. Changing their width to 0 and back to the visible width has nothing to do with it. For testing purposes you could place all your buttons with a reasonable width in the area that is visible without scrolling, and check whether they fire. If some do and others not, it should be easy to find the difference. – Reinhard Männer Oct 31 '16 at 13:17
  • Also, I noticed now, after I once turned off the button (width = 0), I cannot get it back, I will update the question with some new code. – Vodenjak Oct 31 '16 at 15:40
  • If you're just offsetting the x to account for a dynamic number of buttons, and each active button is placed one after the other in a scroll view, sounds like you're taking the long way to do what a collection view could do for you. – Frankie Oct 31 '16 at 17:12
  • To my mind, it is easiest to set the constraints on your buttons in storyboard, as demonstrated in the tutorial I mentioned earlier. These constraints have a `constant` property that can be changed later by code if the code has access to the constraint that was defined in storyboard. Just define in your code a property `@IBOutlet weak var button1WithConstraint: NSLayoutConstraint!` and link it by ctrl-drag to the constraint. When you want to change the width of your button, you simply had to set the new constraint constant like `button1WithConstraint.constant = 100` That’s all! – Reinhard Männer Nov 01 '16 at 09:14
  • Finally managed to do it, thank you Reinhard, I will update the question with information on how I made the scroller work (it was different for me than your link to the tutorial), if you want write an answer so I can accept it! – Vodenjak Nov 02 '16 at 15:19
  • By write an answer I meant an answer concerning the width constraint. And thank you once again :) – Vodenjak Nov 02 '16 at 16:26

0 Answers0