With autolayout, label position is reset when I ch

2020-02-12 17:23发布

I am developing a very simple application in Objective-c.
In the app, the user can change a position of the label by dragging the screen.

Tap & drag the screen, the label moves up and down to match the position of the finger.
When you release your finger, the coordinates information of the label is set to its text.

But the label position is reset at the moment its text is changed.

// IBOutlet UILabel *label

- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    CGPoint touch = [[touches anyObject] locationInView:self.view];
    label.center = CGPointMake(label.center.x, touch.y);
}

- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    CGPoint touch = [[touches anyObject] locationInView:self.view];
    label.center = CGPointMake(label.center.x, touch.y);
}

- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    CGPoint touch = [[touches anyObject] locationInView:self.view];
    label.text = [NSString stringWithFormat:@"y = %f", touch.y];
}

In touchesEnded event, just only change the text of the label,
but the position of it has reset.

I tried to change touchesEnded event like following but it haven't solved the problem.

- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    CGPoint touch = [[touches anyObject] locationInView:self.view];
    label.text = [NSString stringWithFormat:@"y = %f", touch.y];
    label.center = CGPointMake(label.center.x, touch.y);    // add this line
}

I want to resolve this weird behavior without uncheck "Use auto layout".
I'd like to keep using auto layout.

I have 4 screenshots for my app.

4 Screenshots

  1. The first image is a Storyboard.
    I have a label with auto layout constraints.
  2. The second image is a screenshot right after launching app.
  3. The third image is when a user drag the screen,
    and the label move down to match the finger.
  4. The forth image is right after release your finger
    and the label text has changed.

2条回答
唯我独甜
2楼-- · 2020-02-12 17:46

You cannot use auto layout and change the center / frame of things; those are opposites. Do one or the other - not both.

So, you don't have to turn off auto layout, but if you don't, then you must use auto layout, and auto layout only, to position things.

When you move the label, do not change its center - change its constraints. Or at least, having changed its center, change its constraints to match.

Otherwise, when layout occurs, the constraints will put it back where you have told them to put it. And layout does occur when you change the text, and at many other times.

查看更多
放我归山
3楼-- · 2020-02-12 17:59

Solution by OP.

Constraint can be treated as an IBOutlet on Storyboard:
Associating constraints as well as label or other IBOutlet.

// ViewController.h
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController {
    IBOutlet UILabel *label;
    IBOutlet NSLayoutConstraint *lcLabelTop;
}

@end

// ViewController.m
- (void)viewDidLoad {
    [super viewDidLoad];

    UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panAction:)];
    [self.view addGestureRecognizer:pan];
}

- (void)panAction : (UIPanGestureRecognizer *)sender
{
    CGPoint pan = [sender translationInView:self.view];
    lcLabelTop.constant += pan.y;

    if (sender.state == UIGestureRecognizerStateEnded) {
        label.text = [NSString stringWithFormat:@"y = %f", lcLabelTop.constant];
    }

    [sender setTranslation:CGPointZero inView:self.view];
}
查看更多
登录 后发表回答