Search code examples
iosobjective-cxcodeuibuttonarc4random

Scaling arc4random for different screen sizes


I'm making a game that doesn't use Autolayout, and have used constraints to scale everything and it worked perfectly. However I cant seem to figure this out, I'm using arc4random to randomly position X and Y coordinates of a UIButton on the 4.7 inch screen. When I try running it on the smaller screen it plots the UIButton off the screen at times. How can I scale arc4random up and down depending on screen size.

-(void)position{

     Randompositionx = arc4random() %270;
     Randompositionx = Randompositionx + 51;
     Randompositiony = arc4random() %411;
     Randompositiony = Randompositiony +163;

UIButton.center = CGPointMake(Randompositionx, Randompositiony);


}

Solution

  • You should be using arc4random_uniform rather than arc4random and the modulo operator. It gives numbers without "modulo bias".

    You need to adapt the upper value of your random number based on screen size. T_77's answer was a step in the right direction, but still not right.

    The code below assumes the button you want to move is called myButton.

    It uses margin values of 20 all around. Change the values as desired.

    EDIT: I updated it to use the height and width of the button in the position calculation. With the updated code the button should never be closer to any edge than the margin value, even if the button size changes. No magic numbers, either. It should adapt to the size of it's superview.

    -(void)position
    {
      CGRect frame = myButton.superview.bounds;
      CGFloat leftMargin = 20; //use whatever values you want for magins
      CGFloat rightMargin = 20;
      CGFloat topMargin = 20;
      CGFloat bottomMargin = 20;
      CGFloat randomX, randomY;
      CGFloat xMax = frame.size.width-leftMargin-rightMargin-
        button.bounds.size.width/2;
      randomX = arc4random_uniform(xMax) + leftMargin;
      CGFloat yMax = frame.size.height-topMargin-bottomMargin-
        button.bounds.size.height/2;
      randomY = arc4random_uniform(yMax) + topMargin; 
      myButton.center = CGPointMake(randomX, randomY);
    }
    

    Also note that if you're using auto layout you shouldn't move the button's position directly, and instead should have position constraints and modify their constants, then call layoutIfNeeded. Otherwise the first thing that causes your layout to change will cause your button to revert to it's previous position.