0

I have a view with a subview that is designed to show a user what fraction of games they have won and lost, like so: User profile screen The width of the green view is calculated by taking the width of the superview, multiplying it by the fraction of games won (which in this case is .5), and changing the width constraint of the green view to the calculated value.

let percent = Float(won)/Float(self.partiesPlayed) //percent of games won, should be .5 let width = CGFloat(percent) * self.winLoseView.bounds.size.width //multiply width of superview by percent self.greenWidthConstraint.constant = CGFloat(width) //change constraint's constant UIView.animateWithDuration(2, animations: { // animate change self.view.layoutIfNeeded() }) 

enter image description here

The problem is that the width does not appear to be exactly correct, for instance in this example it doesn't appear to be exactly half of the superview.

16
  • are you using auto layout? Commented Jan 2, 2015 at 19:24
  • Yes I am. Instead of changing the view's width, I'm changing its width constraint and reloading constraints. Commented Jan 2, 2015 at 19:26
  • Based on your description ("doesn't appear to be exactly correct")... Silly question time: Have you confirmed via NSLog and/or debugger whether this is a data issue (green width is being set incorrectly) or a constraint/layout issue (the value is being set properly but the resultant layout system isn't what you expect)? Commented Jan 2, 2015 at 19:37
  • ok, the green/red view are totally the width of superview? did you calculate the padding left and right? Commented Jan 2, 2015 at 19:38
  • The superview is a red rectangle, with a green rectangle as the subview. Commented Jan 2, 2015 at 19:39

1 Answer 1

1

Here's another approach: Why not just remove the greenWidthConstraintand re-apply it with a constraint equal to the width of the red view and set the multiplier to the percentage won. That way, if you supported rotation or any other size change, you wouldn't worry about a fixed width value constant. I'm not up to par w/ swift yet, but here's it in Objective-c:

[self.view removeConstraint:self.constraint]; self.constraint = [NSLayoutConstraint constraintWithItem:self.greenView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self.redView attribute:NSLayoutAttributeWidth multiplier:PERCENTAGE constant:0]; [self.view addConstraint:self.constraint]; // Animate the layoutIfNeeded.... 

Here's Swift version: (provided by @milesper)

let percent = Float(won)/Float(self.partiesPlayed) var constraint = NSLayoutConstraint(item: self.greenSection, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: self.winLoseView, attribute: NSLayoutAttribute.Width, multiplier: CGFloat(percent), constant: 0.0 as CGFloat) self.view.addConstraint(constraint) UIView.animateWithDuration(2, animations: { self.view.layoutIfNeeded() }) 
Sign up to request clarification or add additional context in comments.

1 Comment

That worked perfectly! I'm just going to translate it into Swift

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.