2

I have a UIScrollView set up, and am using addSubView to add 5 buttons to it. Here is the code inside my viewDidLoad.

    let codedButton:UIButton = UIButton(frame: CGRectMake(0, 0, 100, 50))
    codedButton.backgroundColor = UIColor.redColor()
    codedButton.setTitle("Button 1", forState: UIControlState.Normal)
    codedButton.addTarget(self, action: #selector(ViewController.buttonAction(_:)), forControlEvents: UIControlEvents.TouchUpInside)
    codedButton.tag = 1
    self.buttonScrollView.addSubview(codedButton)
    
    let codedButton2:UIButton = UIButton(frame: CGRectMake(110, 0, 100, 50))
    codedButton2.backgroundColor = UIColor.redColor()
    codedButton2.setTitle("Button 2", forState: UIControlState.Normal)
    codedButton2.addTarget(self, action: #selector(ViewController.buttonAction(_:)), forControlEvents: UIControlEvents.TouchUpInside)
    codedButton2.tag = 2
    self.buttonScrollView.addSubview(codedButton2)

(all the way to 5.)

The problem that I need help with is... Ultimately, these buttons will be dynamically displayed. Not just a set amount of 5.

How do I adjust the X value of the CGRectMake to automatically "float" new buttons to the right of the button that was just created? In my code above, I am explicitly stating where the X is, but that won't work properly once these buttons become dynamically created in code.

EDIT To clarify my question above: I have attached an image. Note how the buttons always stack horizontally / next to each other, regardless of if there's 2 3 4 or 5. These buttons will be dynamically shown. Therefore, with my code attempt I have provided above, it will not work because it is explicitly setting where to place the buttons on the X axis.

I need to modify my code to perform like the image below. I need my code edited so that it automatically stacks the new buttons horizontally.

Community
  • 1
  • 1
Joe
  • 3,772
  • 3
  • 33
  • 64

3 Answers3

1

I see that you are doing this programmatically. I can't help with the code, but stack views in the storyboard are great. I have a feature in my app where I have 4 buttons, but the user may only see, say, 2 of the 4 buttons.

1) Add the buttons horizontally into the storyboard (They don't need to be perfectly aligned, just enough so that Xcode can recognize it's horizontal rather than vertical.

2) Select all 5 buttons

3) Click on the stack view button in the lower right-hand corner of Xcode (The button with 4 horizontal lines with and an arrow pointing down.

4) In the attributes inspector, choose horizontal as the axis, alignment as center, fill proportionately, play with the spacing, and choose scale to fill as the mode.

5) In the Swift file, you can add or hide the buttons using button.hidden = true / false

NOTE: Keep in mind that stack views are only available with iOS 9 when I last checked

Dan Levy
  • 3,931
  • 4
  • 28
  • 48
  • I am going to research more into this. ios9 is active on 75% of ios devices according to macrumors, so this may very well be a viable solution. – Joe Mar 30 '16 at 03:35
  • Right! Another app I have out on the store is only available for iOS 9 users, but most people are on it anyways – Dan Levy Mar 30 '16 at 19:01
1

Below is an example of the loop you can add to your current implementation of one button to add as many buttons as you would like, and in this example the number of buttons is dependent on the number of button names that you add to the array called "buttonList". For each iteration of the loop it will name the button from the text in the ButtonList and set the tag to its index in the array. It will then calculate the x coordinate of your frame, and in this example I made each button 100px wide, and have a 10px space in between, starting at x coordinate location 0. If you wanted to add 10px space between the first button and the leading edge of the view just increment the index when calculating the x coordinate with: let xCoord = CGFloat(index*buttonWidth + (index+1)*buttonSpace)

You will also need to increase the size of your scroll view to fit buttons as more are added, this is the calculation I used for setting my scroll view width (Increment the buttonSpace width by 1 if adding a leading space to your scroll view) : buttonScrollView.contentSize = CGSizeMake(CGFloat((ButtonList.count * buttonWidth) + ((ButtonList.count + 1) * buttonSpace)), 50)

var ButtonList = ["Button 1", "Button 2", "Button 3"]
let buttonWidth = 100
let buttonSpace = 10
for (index,ButtonText) in ButtonList.enumerate(){
    //calculate the x coordinate of each button
    let xCoord = CGFloat(index*buttonWidth + index*buttonSpace)
    let codedButton:UIButton = UIButton(frame: CGRectMake(xCoord, 0, 100, 50))
    codedButton.backgroundColor = UIColor.redColor()
    codedButton.setTitle(ButtonText, forState: UIControlState.Normal)
    codedButton.addTarget(self, action: #selector(ViewController.buttonAction(_:)), forControlEvents: UIControlEvents.TouchUpInside)
    codedButton.tag = index
    self.buttonScrollView.addSubview(codedButton)
    }
  • It's been a while since I worked on this project that I posted the question about, but when I revisit it I will try this method! Thank you for your very thorough response. – Joe Jun 16 '16 at 01:31
  • I noticed unfortunately that the question was a couple months old, but I stumbled upon this post looking to implement the same button layout in a project of my own so I thought I'd post a solution since there didn't appear to be one. – element4lifex8 Jun 16 '16 at 10:39
0

I do not know exactly if that is what you're asking for.. if not, leave a comment.

Create a counter and name your buttons..

button.name = "name\(counter)"

Get the position of your last button using..

let position = self.childNodeWithName("name\(counter)")?.position

Set the position of your new button..

newButton.position = CGPointMake(position.x + newButton.frame.size.width/2 + oldButton.frame.size.width/2, position.y)

.. your new button is now set right to your last button added

user3138007
  • 637
  • 1
  • 6
  • 19
  • I am unsure how to implement your code within the code that I currently have. I've also edited my initial post to be more clear as to what I need to achieve. – Joe Mar 30 '16 at 01:27