2014-12-22 11 views
7

đây là những gì tôi muốn đạt được: enter image description hereLàm cách nào để tạo hiệu ứng trượt lên UIView bằng tính năng Tự động hoàn tất?

Tôi muốn thực hiện một slide lên phim hoạt hình mà người dùng có thể trượt một UIView2 lên, và UIView2 sẽ ngừng một nửa chiều trên màn hình.

tôi biết làm thế nào để trình bày một UIViewControler modally thông qua một hành động UIButton như vậy:

[self presentViewController:newController animated:NO completion:nil]; 

Tôi cũng biết bạn cần loại mã cho hình ảnh động:

[UIView animateWithDuration:0.5f animations:^{ 
    [self.customView layoutIfNeeded]; 
} completion:^(BOOL finished) { 

}]; 

Tuy nhiên, tôi không chắc chắn làm thế nào để đạt được điều này với UIViews, đặc biệt là kể từ khi tôi sử dụng AutoLayout cho dự án của tôi và tôi sử dụng các ràng buộc để dễ dàng hỗ trợ nhiều kích cỡ màn hình.

Làm cách nào tôi có thể đạt được điều này mà không vi phạm AutoLayout và các ràng buộc mà tôi đã thiết lập?

Cảm ơn

Trả lời

16

Điều tôi thường làm trong trường hợp này là như sau.

Thêm hai ràng buộc vào cảnh của bạn. Một trong những nơi mà UIView2 được căn chỉnh ở dưới cùng của UIView1. Thứ hai, nơi nó được căn giữa của UIView1 (bạn sẽ muốn ctrl + kéo giữa các khung nhìn để thêm các ràng buộc một cách thích hợp). Những ràng buộc ban đầu sẽ xung đột với nhau, và điều đó là tốt.

Thêm IBOutlet s vào bộ điều khiển chế độ xem của bạn cho số NSLayoutConstraints và gán hai ràng buộc mà chúng tôi đã tạo cho những IBOutlet s đó.

Đặt mức độ ưu tiên ràng buộc trong điều kiện ban đầu của bạn thành 999 (tức là ưu tiên ràng buộc trên căn chỉnh đến dưới cùng phải là 999). Đặt mức độ ưu tiên ràng buộc về giới hạn đích đến 998 (tức là ưu tiên ràng buộc trên trung tâm căn chỉnh là 998). Bây giờ bạn sẽ thấy rằng những ràng buộc này sẽ không còn xung đột. Điều này là do ưu tiên trên một ràng buộc sẽ ghi đè lên một ràng buộc khác.

Bạn có thể thấy vị trí này hiện đang hướng đến. Vì vậy, khi bạn muốn animate UIView2 giữa các ràng buộc, trao đổi các ưu tiên và animate!

Code:

@interface MyViewController() 
    @property (nonatomic, weak) IBOutlet NSLayoutConstraint* constraint0; 
    @property (nonatomic, weak) IBOutlet NSLayoutConstraint* constraint1; 
@end 

- (void)someMethodWhereIWantToAnimate 
{ 
    NSInteger temp = self.constraint0.priority; 
    self.constraint0.priority = self.constraint1.priority; 
    self.constraint1.priority = temp; 

    [UIView animateWithDuration:0.3 animations:^{ 
     // Simplest is to use the main ViewController's view 
     [self.view layoutIfNeeded]; 
    }]; 
} 

Để kích hoạt panning và sử dụng rằng để bắt đầu hoạt hình của bạn thêm một cử chỉ Recognizer Pan để điều khiển xem của bạn. Ctrl + kéo từ UIView2 đến Trình nhận dạng cử chỉ Pan và đặt thành gestureRecognizer. Bây giờ, khi bạn kéo trên UIView2, bạn sẽ có thể nhận sự kiện pan.

Thêm một IBAction để xử lý các pan:

- (IBAction)onPan:(id)sender 
{ 
} 

Ctrl + kéo từ trình nhận dạng cử chỉ chảo với bộ điều khiển xem và thiết lập onPan: là hành động gửi.

sender thực sự là trình nhận dạng cử chỉ di chuyển. Vì vậy, chúng tôi sẽ có thể điền vào phương pháp này để xử lý một chảo và có UIView2 theo ngón tay của người dùng và sau đó bắt đầu các hình ảnh động khi họ cho đi.

Hãy bắt đầu điền mã:

- (IBAction)onPan:(id)sender 
{ 
    UIPanGestureRecognizer* recognizer = (UIPanGestureRecognizer*)sender; 
    CGPoint translation = [recognizer translationInView:self.view]; 
    NSLog(@"State: (%d) Translation in view: (%f, %f)", recognizer.state, translation.x, translation.y); 
} 

Nếu bạn chạy với mã này, và kéo ngón tay của bạn trên UIView2, bạn sẽ thấy kết quả như thế này:

State: (1) Translation in view: (0.000000, -2.500000) 
State: (2) Translation in view: (0.500000, -7.500000) 
State: (2) Translation in view: (0.500000, -7.500000) 
State: (2) Translation in view: (1.500000, -12.000000) 
State: (2) Translation in view: (2.500000, -16.500000) 
State: (2) Translation in view: (2.500000, -19.500000) 
State: (2) Translation in view: (2.500000, -24.500000) 
State: (2) Translation in view: (2.500000, -25.000000) 
State: (2) Translation in view: (2.500000, -25.500000) 
State: (2) Translation in view: (2.500000, -27.000000) 
State: (2) Translation in view: (2.500000, -29.500000) 
State: (2) Translation in view: (2.500000, -31.000000) 
State: (2) Translation in view: (2.500000, -31.500000) 
State: (3) Translation in view: (2.500000, -31.500000) 

Chú ý rằng các giá trị liên tục tăng lên. Chúng tôi sẽ muốn số tiền gia tăng. Lưu ý trạng thái trong nhật ký. Trạng thái (1) là bắt đầu kéo. Trạng thái (2) đang kéo thay đổi. Trạng thái (3) đang kéo kết thúc. Sử dụng thông tin này, chúng ta có thể tính toán delta.

Thêm một tài sản CGPoint để điều khiển xem của bạn và thêm UIView2 như một IBOutlet cũng như:

@property (nonatomic) CGPoint lastTranslation; 
@property (nonatomic, weak) IBOutlet UIView* uiView2; 

Cuối cùng, chúng ta hãy điền vào mẫu cuối cùng của phương pháp chảo của chúng tôi:

- (IBAction)onPan:(id)sender 
{ 
    UIPanGestureRecognizer* recognizer = (UIPanGestureRecognizer*)sender; 
    CGPoint delta; 
    switch(recognizer.state) { 
     case UIGestureRecognizerStateBegan: 
      // On state begin: delta is the translation. Store it in our member for later user. 
      self.lastTranslation = delta = [recognizer translationInView:self.view]; 
      break; 
     case UIGestureRecognizerStateChanged: 
      // On state changed: calculate the difference between the translation and our 
      // previous translation. 
      delta = CGPointApplyAffineTransform([recognizer translationInView:self.view], CGAffineTransformMakeTranslation(-self.lastTranslation.x, -self.lastTranslation.y)); 
      self.lastTranslation = [recognizer translationInView:self.view]; 
      break; 
     case UIGestureRecognizerStateEnded: 
      // On state ended: Let's just do the constraint animation. 
      [self someMethodWhereIWantToAnimate]; 
      break; 
     default: 
      break; 
    } 
    delta.x = 0; // Forces only vertical drag on the UIView2. 
    self.uiView2.center = CGPointApplyAffineTransform(self.uiView2.center, CGAffineTransformMakeTranslation(delta.x, delta.y)); // Move our uiView2 based on the delta. 
    NSLog(@"State: (%d) Translation in view: (%f, %f)", recognizer.state, delta.x, delta.y); 
} 

nên này giúp bạn tốt trên con đường của bạn. Bạn có thể muốn xem xét chỉnh sửa hoạt ảnh UIView về các ràng buộc một chút dựa trên phương thức của phương thức pan của cử chỉ, nhưng tôi sẽ để lại như một bài tập.

+0

Tôi giả định ràng buộc1 là ràng buộc trung tâm theo chiều dọc? ... có lẽ tôi đã bỏ lỡ việc đọc nhưng ràng buộc nào ràng buộc 0 tương ứng với? ... dưới cùng? – Pangu

+0

Có, ràng buộc0 sẽ là ràng buộc để căn chỉnh về phía dưới. Constraint1 sẽ là ràng buộc dọc trung tâm. @Pangu –

+0

những gì về một thực tế là UIView2 là một phần ra khỏi cửa sổ của UIView1 bên trong hoàn toàn bên trong UIView1? ... sẽ không có trong chính nó cũng tạo ra xung đột hạn chế riêng của mình? – Pangu

Các vấn đề liên quan