2010-09-03 9 views
146

Tôi có giao thức UIApplicationDelegate trong lớp AppDelegate.m chính của tôi, với phương thức applicationDidBecomeActive được xác định.Xử lý ứng dụngDidBecomeActive - "Bộ điều khiển chế độ xem có thể phản ứng với ứng dụng đang hoạt động như thế nào?"

Tôi muốn gọi phương thức khi ứng dụng trả về từ nền, nhưng phương thức này nằm trong một trình điều khiển chế độ xem khác. Làm thế nào tôi có thể kiểm tra xem bộ điều khiển xem hiện đang hiển thị trong phương pháp applicationDidBecomeActive và sau đó thực hiện cuộc gọi đến một phương pháp trong bộ điều khiển đó?

Trả lời

275

Mọi lớp trong ứng dụng của bạn có thể trở thành "người quan sát" cho các thông báo khác nhau trong ứng dụng. Khi bạn tạo (hoặc tải) bộ điều khiển xem của bạn, bạn sẽ muốn đăng ký nó như một người quan sát cho UIApplicationDidBecomeActiveNotification và chỉ định phương thức mà bạn muốn gọi khi thông báo đó được gửi đến ứng dụng của bạn.

[[NSNotificationCenter defaultCenter] addObserver:self 
             selector:@selector(someMethod:) 
              name:UIApplicationDidBecomeActiveNotification object:nil]; 

Đừng quên tự dọn dẹp! Hãy nhớ tự xóa mình là người quan sát khi chế độ xem của bạn biến mất:

[[NSNotificationCenter defaultCenter] removeObserver:self 
               name:UIApplicationDidBecomeActiveNotification 
               object:nil]; 

Thông tin thêm về Notification Center.

+0

Tuyệt vời. Không nghĩ đến việc sử dụng 'NSNotificationCenter'. Cảm ơn bạn! – Calvin

+3

Chỉ cần một lỗi đánh máy trong dòng mã đó (thiếu 'tên'): [[NSNotificationCenter defaultCenter] addObserver: tự chọn: @selector (someMethod :) tên: UIApplicationDidBecomeActiveNotification object: nil]; – Johnus

+0

@Johnus - cảm ơn vì đã bắt được. Đã cập nhật câu trả lời của tôi. –

15

Swift 2 tương đương:

let notificationCenter = NSNotificationCenter.defaultCenter() 

// Add observer: 
notificationCenter.addObserver(self, 
    selector:Selector("applicationWillResignActiveNotification"), 
    name:UIApplicationWillResignActiveNotification, 
    object:nil) 

// Remove observer: 
notificationCenter.removeObserver(self, 
    name:UIApplicationWillResignActiveNotification, 
    object:nil) 

// Remove all observer for all notifications: 
notificationCenter.removeObserver(self) 

// Callback: 
func applicationWillResignActiveNotification() { 
    // Handle application will resign notification event. 
} 
+0

Nơi tốt nhất để đặt 'removeObserver' trong Swift: phương thức' deinit'. –

+0

Nói chung, việc truy cập tự trong deinit không được thông báo; tại thời điểm này, bản thân ở giữa được phân bổ đầy đủ và đang được phân bổ – Zorayr

+0

Bạn sẽ removeObserver ở đâu? –

32

Swift 3, 4 tương đương:

thêm quan sát viên

NotificationCenter.default.addObserver(self, 
    selector: #selector(applicationDidBecomeActive), 
    name: .UIApplicationDidBecomeActive, 
    object: nil) 

loại bỏ quan sát

NotificationCenter.default.removeObserver(self, 
    name: .UIApplicationDidBecomeActive, 
    object: nil) 

callback

@objc func applicationDidBecomeActive() { 
    // handle event 
} 
+0

Tôi gọi nó ở đâu? –

+0

@ user8169082, bạn thêm một người quan sát bất cứ nơi nào bạn cần để bắt đầu nhận thông báo. Bạn có thể thêm nó vào ví dụ 'viewDidLoad' hoặc' viewWillAppear: animated'. Và bạn có thể loại bỏ một người quan sát khi bạn không còn cần thông báo nữa, hoặc khi người quan sát của bạn sẽ được deallocated trong phương thức deinit – igrek

1

Với Swift 4, Apple khuyến nghị thông qua một cảnh báo trình biên dịch mới mà chúng tôi tránh việc sử dụng các #selector trong kịch bản này. Sau đây là một cách an toàn hơn nhiều để thực hiện điều này:

Đầu tiên, tạo một var lười biếng mà có thể được sử dụng bởi các thông báo:

lazy var didBecomeActive: (Notification) -> Void = { [weak self] _ in 
    // Do stuff 
} 

Nếu bạn cần thông báo thực tế được bao gồm, chỉ cần thay thế _ với notification.

Tiếp theo, chúng tôi thiết lập thông báo để quan sát ứng dụng đang hoạt động.

func setupObserver() { 
    _ = NotificationCenter.default.addObserver(forName: .UIApplicationDidBecomeActive, 
               object: nil, 
               queue: .main, 
               using: didBecomeActive) 
} 

Sự thay đổi lớn ở đây là thay vì gọi một #selector, bây giờ chúng ta gọi var tạo ở trên. Điều này có thể loại bỏ các tình huống mà bạn gặp sự cố chọn không hợp lệ.

Cuối cùng, chúng tôi sẽ xóa người quan sát.

func removeObserver() { 
    NotificationCenter.default.removeObserver(self, name: .UIApplicationDidBecomeActive, object: nil) 
}