Sự khác biệt giữa -[UIViewController viewWillAppear:]
và là -[UIViewController viewDidAppear:]
gì?
Sự khác biệt giữa -[UIViewController viewWillAppear:]
và là -[UIViewController viewDidAppear:]
gì?
Câu trả lời:
Nói chung, đây là những gì tôi làm:
1) ViewDidLoad - Bất cứ khi nào tôi thêm các điều khiển vào một chế độ xem sẽ xuất hiện cùng với chế độ xem, ngay lập tức, tôi đặt nó trong phương thức ViewDidLoad. Về cơ bản phương thức này được gọi bất cứ khi nào khung nhìn được tải vào bộ nhớ. Vì vậy, ví dụ, nếu chế độ xem của tôi là một biểu mẫu có 3 nhãn, tôi sẽ thêm các nhãn ở đây; quan điểm sẽ không bao giờ tồn tại mà không có những hình thức.
2) ViewWillAppear : Tôi thường sử dụng ViewWillAppear chỉ để cập nhật dữ liệu trên biểu mẫu. Vì vậy, với ví dụ trên, tôi sẽ sử dụng điều này để thực sự tải dữ liệu từ miền của mình vào biểu mẫu. Việc tạo UIViews khá tốn kém và bạn nên tránh càng nhiều càng tốt khi thực hiện điều đó trên phương thức ViewWillAppear, vì điều này được gọi, điều đó có nghĩa là iPhone đã sẵn sàng hiển thị UIView cho người dùng và bất cứ điều gì nặng nề bạn làm ở đây sẽ tác động đến hiệu suất theo cách rất dễ thấy (như hoạt hình bị trì hoãn, v.v.).
3) ViewDidAppear : Cuối cùng, tôi sử dụng ViewDidAppear để bắt đầu các luồng mới cho những thứ sẽ mất nhiều thời gian để thực thi, ví dụ như thực hiện cuộc gọi dịch vụ web để lấy thêm dữ liệu cho biểu mẫu ở trên. Điều tốt là vì chế độ xem đã tồn tại và đang được hiển thị cho người dùng, bạn có thể hiển thị thông báo "Đang chờ" cho người dùng trong khi bạn nhận được dữ liệu.
viewWillAppear
? Bạn có nghĩa là tải qua mạng? Nhưng bạn cũng đề nghị tải công cụ trong viewDidAppear
?
ViewDidAppear
bạn sẽ dễ khiến người dùng nhầm lẫn về UI :)
viewDidLoad === >>> Đặt mã khởi tạo của bạn ở đây. Không đặt dữ liệu động có thể thay đổi trong vòng đời xem. Vì vậy, nếu bạn đang lấy dữ liệu từ dữ liệu cốt lõi, bạn không muốn làm điều đó ở đây nếu điều này có thể thay đổi trong suốt vòng đời của chế độ xem. Ví dụ: giả sử bạn có bộ điều khiển tab. Bạn chuyển từ tab1 sang tab2 và thay đổi một cái gì đó trên mô hình trong tab2. Nếu bạn quay lại tab1 và mã mô hình của bạn đã được thực hiện trong viewDidLoad, điều này sẽ không được cập nhật (giả sử bạn không sử dụng KVO hoặc NSFetchedResultsControll, v.v.).
viewWillAppear === >>> Điều này được gọi mỗi khi chế độ xem sắp xuất hiện, cho dù chế độ xem đã có trong bộ nhớ hay chưa. Đặt mã động của bạn ở đây, chẳng hạn như logic mô hình.
viewDidAppear === >>> Đặt các thao tác đắt tiền ở đây mà bạn chỉ muốn làm nếu bạn chắc chắn chế độ xem trên màn hình, chẳng hạn như các cuộc gọi mạng.
Lưu ý: nếu ứng dụng của bạn được chạy nền và trở về nền trước, bạn cần xử lý việc này bằng NSNotificationCenter. Tôi đã viết mã ra cho điều đó trong các ý kiến dưới đây. Bạn có thể nghĩ viewWillAppear / viewDidAppear sẽ kích hoạt. Đặt một điểm dừng ở đó và kiểm tra nó. Nó không cháy. Vì vậy, nếu có gì đó đã thay đổi cho ứng dụng của bạn khi ứng dụng chạy ở chế độ nền, bạn sẽ cần cập nhật thông báo đó bằng thông báo.
Một vài quan sát:
Các viewDidLoad
phương pháp được gọi khi xem được khởi tạo đầu tiên. IBOutlet
tài liệu tham khảo được nối vào thời điểm này đã được gọi, nhưng không phải trước đó. Các frame
số quan điểm có thể không được thành lập vào thời điểm này đã được gọi là, mặc dù. Đây là một nơi tuyệt vời để thêm / cấu hình các cuộc phỏng vấn và các ràng buộc liên quan của chúng. Nhưng nếu bạn đang thực hiện bất kỳ cấu hình thủ công nào của các frame
giá trị trên cơ sở kích thước của chế độ xem chính, cấu hình của các khung đó sẽ được hoãn lại cho đến khi viewWillAppear
hoặc viewDidLayoutSubviews
.
Các viewWillAppear
phương pháp được gọi khi trình bày quan điểm trong hệ thống phân cấp xem là sắp bắt đầu. Đáng chú ý, điều này được gọi khi bắt đầu hoạt hình (nếu có) của phần trình bày của chế độ xem. Đồng hành của nó, viewWillDisappear
rõ ràng được gọi khi quá trình chuyển đổi khỏi quan điểm này bắt đầu.
Các viewDidAppear
phương pháp được gọi khi trình bày quan điểm được thực hiện, đặc biệt là khi bất kỳ và tất cả các hình ảnh động liên quan đã hoàn tất. Đồng hành của nó, viewDidDisappear
rõ ràng được gọi khi quá trình chuyển đổi khỏi quan điểm này được thực hiện.
Hai cảnh báo quan trọng:
viewDidLoad
được gọi một lần và chỉ một lần, khi chế độ xem được khởi tạo lần đầu tiên. Mặt khác, viewWillAppear
và viewDidAppear
sẽ được gọi không chỉ khi chế độ xem được trình bày lần đầu tiên, mà mỗi lần tiếp theo, cùng một quan điểm trong câu hỏi được trình bày lại. Ví dụ, khi bạn lần đầu tiên trình bày một khung nhìn, cả ba phương thức này sẽ được gọi. Nếu chế độ xem trong câu hỏi sau đó trình bày một chế độ xem khác bị loại bỏ sau đó, viewWillAppear
và viewDidAppear
thường sẽ được gọi lại khi chế độ xem trong câu hỏi được thêm vào và hoạt hình trở lại vào hệ thống phân cấp chế độ xem, nhưng viewDidLoad
sẽ không. viewDidLoad
chỉ được gọi khi trường hợp cụ thể này được tạo lần đầu tiên.
Vì vậy, nếu bạn muốn làm gì đó mỗi khi một khung nhìn xuất hiện lại (ví dụ: bạn loại bỏ hoặc bật lại nó), hãy thực hiện trong viewWillAppear
hoặc viewDidAppear
. Nếu bạn muốn nó chỉ xảy ra khi chế độ xem được khởi tạo lần đầu tiên, hãy thực hiện điều đó trong viewDidLoad
.
Việc kêu gọi viewWillAppear
không đảm bảo rằng việc chuyển đổi sang quan điểm đó sẽ được hoàn thành. Đáng chú ý, nếu bạn đang sử dụng chuyển đổi tương tác được điều khiển bởi đầu vào của người dùng thời gian thực, nhưng quá trình chuyển đổi tương tác đó có thể bị hủy. Tức là, chỉ vì viewWillAppear
được gọi, nó không có nghĩa là viewDidAppear
sẽ được gọi. Nói chung là như vậy, nhưng nếu cử chỉ tương tác bị hủy thì sẽ không (vì quá trình chuyển đổi không bao giờ kết thúc).
Tại WWDC 2013, trong bối cảnh chuyển tiếp tương tác, một người dẫn chương trình nói đùa rằng họ nên đổi tên viewWillAppear
để viewMightAppear
"hoặc viewWillProbablyAppear
, hoặc iReallyWishThisViewWouldAppear
".
Một ví dụ về cử chỉ tương tác tích hợp là khi sử dụng UINavigationController
và bạn "vuốt từ cạnh trái" để bắt đầu một cửa sổ bật lên của chế độ xem. Các viewWillAppear
sẽ được gọi cho quan điểm mà bạn đang popping, nhưng nếu bạn hủy rằng "vuốt từ mép trái" để trở lại quan điểm mà từ đó bạn bắt đầu cử chỉ pop này, các cửa sổ pop bị hủy bỏ và viewDidAppear
cho quan điểm bạn bắt đầu bật trở lại sẽ không bao giờ được gọi.
Hiệu quả ròng của việc này là bạn nên cẩn thận rằng bạn không viết mã giả định rằng mọi cuộc gọi đến viewWillAppear
sẽ được thực hiện theo sau bởi một cuộc gọi đến viewDidAppear
. Nếu quá trình chuyển đổi bị hủy bỏ, điều này sẽ không xảy ra.
1) ViewWillAppear : Chế độ xem được tải thực sự trong bộ nhớ, được gọi một lần trong trình điều khiển chế độ xem và có khung của nó, nhưng vẫn không xuất hiện cho người dùng
2) ViewDidAppear : Bộ điều khiển được thêm vào cấu trúc phân cấp chế độ xem, do đó bạn có thể trình bày cho bộ điều khiển tiếp theo, ngoài ra, chế độ xem đã bố trí các bản xem trước
Cái trước xảy ra trước khi cái nhìn xuất hiện và cái sau xảy ra sau đó.
Tóm lại:
-viewWillAppear -> cập nhật dữ liệu (tải lại dữ liệu từ chế độ xem bảng)
-viewDidAppear -> các hoạt động đắt tiền (cuộc gọi API với một tiến trình tốt đẹp!)
Usecase , tức là khi nào tôi nên sử dụng?
viewDidLoad
- khi các nhãn, nút (i, e bất kỳ điều khiển / xem trước nào) được kết nối với tệp giao diện của Chế độ xem và nếu bạn muốn tải tất cả các mục này cùng lúc với Chế độ xem của Trình điều khiển và nếu bạn muốn tải tệp này vào bộ nhớ một lần và được thực hiện với nó
viewWillAppear
- giả sử, bạn muốn thay đổi màu nền của chế độ xem mỗi khi viewContoder xuất hiện trên màn hình. Hoặc thực tế hơn nếu bạn muốn màu nền DarkMode vào ban đêm trong ngày và màu sáng của chế độ xem nền vào ban ngày, hãy tìm mã này trongviewWillAppear
Một usecase tốt khác tại đây https://stackoverflow.com/a/39395865/5438240
Cũng lưu ý rằng, nếu bạn đang sử dụng ngăn xếp Điều hướng ( UINavigationController
), thì trình điều khiển viewCont ra sắp xuất hiện có viewWillDisappear()
tên được gọi và Trình điều khiển ViewCont tiếp theo sẽ nằm trên đầu ngăn xếp sẽ viewWillAppear()
được gọi