2012-02-29 34 views
14

Tôi đang tạo lớp xem chia nhỏ thân thiện với chế độ xem tự động cho một trong các ứng dụng của tôi. Trong số các tính năng khác nhau của nó là nó có thể sụp đổ các tấm, và có thể animate sự sụp đổ của họ, nhiều như bạn có thể đã thấy NSSplitView làm.NSLayoutConstraint.constant bỏ qua hoạt ảnh

Kể từ khi tôi đang sử dụng hạn chế, tôi đạt được điều này bằng cách đặt một chiều rộng yêu cầu = (chiều rộng hiện hành) hạn chế về cửa sổ, và sau đó thiết lập các hằng số 0 hạn chế trong một thời trang hoạt hình:

- (NSLayoutConstraint*)newHiddenConstraintAnimated:(BOOL)animated { 
    NSLayoutConstraint * constraint = [NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:NSWidth(self.view.frame)]; 
    constraint.priority = NSLayoutPriorityRequired; 

    CABasicAnimation * anim = [CABasicAnimation animation]; 
    anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]; 
    anim.duration = 0.2; 
    constraint.animations = [NSDictionary dictionaryWithObject:anim forKey:@"constant"]; 

    [self.view addConstraint:constraint]; 

    [(animated ? constraint.animator : constraint) setConstant:0.0]; 

    return constraint; 
} 

Công trình này đẹp mắt. Thật không may, mở rộng cửa sổ sau này không tốt như vậy.

- (void)removeHiddenConstraintAnimated:(BOOL)animated { 
    if(!animated) { 
     [self.view removeConstraint:self.hiddenConstraint]; 
    } 
    else { 
     NSLayoutConstraint * constraint = self.hiddenConstraint; 
     NSView * theView = self.view; 

     [NSAnimationContext beginGrouping]; 

     [constraint.animator setConstant:self.width]; 

     [NSAnimationContext currentContext].completionHandler = ^{ 
      [theView removeConstraint:constraint]; 
     }; 

     [NSAnimationContext endGrouping]; 
    } 

    self.hiddenConstraint = nil; 
} 

Nếu tôi chèn một số mã thời gian, tôi có thể thấy trình xử lý hoàn thành kích hoạt gần như ngay lập tức, loại bỏ ràng buộc trước khi thời gian hoạt ảnh. Đặt thời lượng trên NSAnimationContext không có hiệu lực.

Bất kỳ ý tưởng nào tôi có thể làm sai ở đây?

+0

Bạn đã bao giờ kết thúc lớp xem chia tách này chưa? Khả năng của nó sẽ mở nguồn? –

+0

Tôi không có kế hoạch vào lúc này. Nó khá chuyên dụng cho ứng dụng này và tôi tin rằng 'NSSplitView' trong [PURRDACTED] đã được thiết kế lại để hoạt động tốt hơn với tính năng tự động trả lời. –

+0

Ồ, vâng. Liên quan đến [redacted], nó có tính năng tốt đẹp liên quan đến bố trí tự động, nhưng tất nhiên nó không tương thích ngược với các mục tiêu cũ hơn. Oh well, tôi sẽ tự mình đoán! :) –

Trả lời

15

Bạn cần phải đầu tiên thiết lập xử lý hoàn tất và chỉ sau đó gửi thông điệp tới proxy hoạt hình. Nếu không, có vẻ như thiết lập trình xử lý hoàn thành sau khi hoạt ảnh bắt đầu kích hoạt nó ngay lập tức và hằng số bị xóa trước khi hoạt ảnh có thời gian kết thúc. Tôi vừa kiểm tra điều này với một đoạn mã đơn giản:

[NSAnimationContext beginGrouping]; 
    NSAnimationContext.currentContext.duration = animagionDuration; 
    NSAnimationContext.currentContext.completionHandler = ^{[self removeConstraint:collapseConstraint];}; 
    [collapseConstraint.animator setConstant:expandedHeight]; 
    [NSAnimationContext endGrouping]; 

này hoạt động hoàn hảo, nhưng nếu bạn thiết lập xử lý hoàn thành sau -setConstant:, các hình ảnh động không có cơ hội để chạy.

+0

Wow, điều đó thực sự hiệu quả. Cảm ơn vì tiền hỗ trợ! –

+0

Không có gì cả, một thời gian trước tôi đã gặp vấn đề tương tự, và đó là câu hỏi của bạn đã dẫn tôi đến thử nghiệm :) – skh

1

Tôi chỉ nhận được để hiểu thấu với công cụ này bản thân mình vì vậy đây có thể là một phân tích ngây thơ nhưng:

Dường như với tôi rằng bạn đang xác định rằng một hình ảnh động trên tài sản của những hạn chế (trong khối khác của bạn) nhưng, sau đó, ngay lập tức đặt tham chiếu đến ràng buộc thành nil (có khả năng phát hành nó) trước khi hoạt ảnh có cơ hội chạy.

Tôi hy vọng rằng bạn sẽ muốn đặt ẩnConstraint thành nil từ bên trong hoặc được kích hoạt bởi khối hoàn thành hoạt ảnh.

Lưu ý rằng nếu như có thể, tôi sai tôi sẽ đánh giá cao một từ hoặc hai về việc tại sao để giúp tôi hiểu nó tốt hơn :)

+0

Giả sử rằng một khung nhìn sở hữu bất kỳ ràng buộc nào bạn thêm vào nó, vì vậy ngay cả khi ràng buộc không được tham chiếu thông qua thuộc tính 'hiddenConstraint', nó vẫn được tham chiếu bởi danh sách các ràng buộc của khung nhìn. Nó cũng được giữ bởi chính khối, vì các khối giữ lại các giá trị của bất kỳ biến đối tượng nào bạn sử dụng trong chúng. –

+0

Như Peter đã nói, 'ràng buộc' là một tham chiếu mạnh mẽ và được chặn bởi khối, và thậm chí nếu nó không phải là khung nhìn vẫn giữ nguyên ràng buộc. Có hàng trăm ràng buộc trong một autolayout phức tạp vừa phải, và đại đa số chỉ được tham chiếu bởi các khung nhìn sở hữu chúng. –

+0

Cảm ơn các bạn đã trả lời loại. –

3

Việc xử lý hoàn thành được bắn ngay lập tức vì nó nghĩ rằng không có bất kỳ các hoạt ảnh cần được chạy. Tôi sẽ kiểm tra và xác nhận rằng hoạt ảnh bạn đã tạo vẫn được đính kèm với chế độ xem. Theo mặc định CABasicAnimation được đặt để tự xóa khi hoàn thành theo cách của thuộc tính removeOnCompletion mà nó kế thừa từ CAAnimation (theo mặc định được đặt thành YES).

bạn sẽ muốn

anim.removedOnCompletion = NO; 
+0

Thêm 'anim.removedOnCompletion = NO;' không có hiệu lực. Đề nghị tốt, mặc dù. –

12

Tôi đồng ý, điều này là khá lạ, và cũng có thể là một lỗi. Tôi chắc chắn sẽ báo cáo nó như vậy bởi vì, theo sự hiểu biết tốt nhất của tôi, công việc này nên.

tôi đã có thể để làm cho nó hoạt động bằng cách sử dụng phương pháp NSAnimationContext lớp +runAnimationGroup:completionHandler: thay vì những điều khoản beginGroupingendGrouping:

[NSAnimationContext runAnimationGroup:^(NSAnimationContext* context){ 
    [constraint.animator setConstant:self.width]; 
} completionHandler:^(void){ 
    [theView removeConstraint:constraint]; 
    NSLog(@"completed"); 
}]; 
+0

Than ôi, điều này dường như không ảnh hưởng đến mã của tôi. Tôi có lẽ sẽ gửi một radar, mặc dù; điều này chắc chắn có vẻ như nó phải làm việc. –

+0

Thật kỳ quặc. Nó chắc chắn hoạt động tốt ở đây. –

+0

Làm việc cho tôi. – stevex

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