2012-04-14 15 views
9

Tôi hy vọng đây là một câu hỏi đơn giản. Nếu tôi có một UINavigationController và tôi đẩy một bộ điều khiển xem mới vào ngăn xếp với một chuyển tiếp hoạt hình, làm thế nào tôi có thể phát hiện khi hoạt hình đã hoàn thành và bộ điều khiển xem mới trên màn hình?Làm thế nào để phát hiện khi hoạt ảnh UINavigationController kết thúc?

Tôi có một vài tình huống mà tôi cần phải đẩy một bộ điều khiển mới mà sau đó phải thực hiện một thao tác dài. Trước tiên tôi muốn đẩy chế độ xem mới để có nội dung nào đó trên màn hình trước khi tôi bắt đầu chặn luồng chính trong một thời gian dài. Nếu tôi thực hiện thao tác push ngay sau nhiệm vụ chạy dài của tôi, khung nhìn sẽ không hiển thị cho đến sau khi cả hai được thực hiện tất nhiên và luồng chính có thể xử lý các sự kiện một lần nữa.

Vì vậy, những gì tôi muốn làm có thể phát hiện trong bộ điều khiển mới khi hoạt ảnh được thực hiện và chế độ xem hiển thị trên màn hình, sau đó bắt đầu tác vụ.

Trả lời

20

+1 đề xuất của @ DHamrick vì không chặn chủ đề chính.

Để trả lời câu hỏi ban đầu, bạn có thể phát hiện những thay đổi viewController ở hai nơi:

  1. Các viewController bạn vừa đẩy sẽ nhận viewWillAppear:viewDidAppear: tin nhắn. Nếu bạn muốn biết khi nào một viewController cụ thể xuất hiện, hãy thực hiện các phương thức này.

  2. Phương thức navigationController:didShowViewController:animated: được đề cập bởi @Mike Z được gửi đến navigationController's delegate. Bạn sẽ cần gán một đối tượng làm đại biểu đó để nhận được thông báo này. Sau đó, bạn sẽ biết mỗi thời gian một chế độ xemController xuất hiện.

+0

viewDidAppear trên bộ điều khiển xem có vẻ là những gì tôi muốn. Tôi không thể làm công việc này trên một thread riêng biệt bởi vì mã đang được thực hiện không phải là thread an toàn. Cảm ơn tất cả các đề xuất mặc dù. – eodabash

3

tôi đã không kiểm tra hoặc thực hiện điều này bản thân mình, nhưng các tài liệu âm thanh như:

navigationController:didShowViewController:animated:

mô tả như sau: Gửi đến người nhận ngay sau khi bộ điều khiển chuyển hướng hiển thị xem và chuyển hướng các thuộc tính mục một cái nhìn khiển của .

Nếu không,

setAnimationDidStopSelector: có thể là thứ phù hợp với bạn.

Được mô tả là: Đặt tin nhắn để gửi đến hoạt ảnh được ủy quyền khi hoạt ảnh dừng lại.

5

Thay vì chặn luồng chính, bạn nên tìm cách thực hiện thao tác chạy dài bên trong một luồng khác hoặc thậm chí tốt hơn, sử dụng hàng đợi GCD.

dispatch_queue_t backgroundQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, NULL); 
dispatch_async(backgroundQueue, ^{ 
    // Do your long running code 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     //Update your UI 
    }); 
}); 

Bạn có thể đặt mã này vào số viewDidLoad: để bạn biết giao diện người dùng của mình đã được tải. Điều này cũng có nghĩa là bạn không phải dựa vào thời gian của hoạt ảnh.

+0

Ngoài ra, tại sao 'dispatch_get_global_queue()' thay vì 'dispatch_queue_create()'? Tôi đã luôn luôn được sử dụng sau này, nhưng nhìn lại, chỉ có một vài trường hợp mà tôi cần hàng đợi nối tiếp chặt chẽ, nhưng tôi đoán tôi có thể chuyển sang hàng đợi đồng thời. Viết tắt của hiển nhiên (ví dụ: sử dụng nối tiếp khi bạn cần), là có bất kỳ suy nghĩ về hàng đợi nối tiếp vs đồng thời? – Rob

+0

Tôi thường tạo hàng đợi khi tôi muốn đảm bảo quyền truy cập đơn lẻ vào tài nguyên đã cho.Ví dụ: nếu tôi có kết nối cơ sở dữ liệu mà tôi muốn đảm bảo không được truy cập đồng thời. – DHamrick

+0

Vâng, tôi sử dụng một hàng đợi cho cùng một lý do chính xác và một trong đó tôi sẽ để lại một trong những cách đó (đó là tài liệu tham khảo của tôi để "nơi tôi cần hàng đợi nối tiếp đúng"). Nhưng tôi đoán là tôi đã có thói quen luôn tạo ra hàng đợi của riêng mình, nhưng bạn làm cho tôi nhận ra rằng điều đó là không cần thiết (và có lẽ không phải là sử dụng tốt tài nguyên của hệ thống). Tôi sẽ bắt đầu sử dụng 'dispatch_get_global_queue()' nhiều hơn. Cảm ơn vì sự thấu hiểu. (BTW, đây là những gì tôi thích về SO.) – Rob