簡體   English   中英

從其SuperView中刪除視圖,通知iPhone上的子視圖

[英]Removing View from its SuperView, Notifying the Subviews on iPhone

從超級視圖中刪除視圖時會觸發什么事件? 它的子視圖是否收到任何消息? 例如,我將subview2和subview3添加到subview1中,如下所示:

super_view-> subview1-> subview2-> subview3

如果我刪除subview1例如

[subview1 removeFromSuperview]; 

它的子視圖(subview2和subview3)接收什么事件?

有沒有辦法讓子視圖知道其超級視圖已刪除?

它取決於subview2和subview3的保留計數。 如果您通過[[UIView alloc] initWithFrame:frame]創建它們,然后將它們添加為子視圖,則它們的保留計數為2。(或3,如果您將引用保留在保留的屬性中,即self.subview2 = [[...

因此,如果要在發布subview1時發布它們,請確保在將它們添加為子視圖后再給它們一個版本,以便它們的保留計數只是添加為子視圖的一個。 像這樣

UIView* subview2 = [[UIView alloc] initWithFrame:myFrame];
[subview1 addSubview:subview2];
[subview2 release];

由於此問題仍未解決,因此有一個答案:

@implementation MySubview
- (void)willMoveToSuperview:(UIView *)newSuperview {
  if (!newSuperview) {
    // I'm being removed from my superview.
  }
}
- (void)didMoveToSuperview {
  if (!self.superview) {
    // I no longer have a superview.
  }
}
@end

如果您需要相反的操作,則可以通過以下方法通知超級視圖其子視圖已退出。

@implemenation MySuperview
- (void)willRemoveSubview:(UIView *)subview {
  // I'm about to remove this view.
}
@end

它的子視圖(subview2和subview3)接收什么事件?
通知了subview1 ,但是subview2subview3需要通過subview1傳遞該消息(這不會自動完成)。

有沒有辦法讓子視圖知道其超級視圖已刪除?
您可以創建一個簡單的委托協議,也可以為此擴展UIView

@implementation UIView (superview_notification)
- (void)notifyMyChildrenAboutTheSuperviewChange {
  [[self subviews] makeObjectsPerformSelector:@selector(notifyMyChildrenAboutTheSuperviewChange)];
}
@end

但是請記住,如果您真的想知道何時不再在屏幕上顯示它們(並且它們沒有超級視圖,這是您的目標的第二要務),則所有子視圖將通過UIWindow鏡像通知上述方法。

@implementation MySubview
- (void)willMoveToWindow:(UIWindow *)newWindow {
  if (!newWindow) {
    // I'm being removed from the screen.
  }
}
- (void)didMoveToWindow {
  if (!self.window) {
    // I'm offscreen.
  }
}
@end

我認為subview1本身被刪除(至少在文檔中未提及)時,subviews(2,3)不會收到任何事件。

編輯

仔細考慮一下...我相信subviews(2,3)在釋放subview1時本身不會接收事件。

但是,如果不保留subview1,則釋放subview1的副作用是,其ref計數將達到0,並且將被釋放。 在解除分配期間,subview1將釋放其所有子視圖。

在這種情況下,它們將被釋放,我不確定這是否是您所追求的。

參見簡的答案。

當視圖從其父視圖中移除時,其所有子視圖也將從中移除,從而導致保留球減少一個。

看下面的代碼片段:

randomImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"oldbg.png"]];
randomImage.frame = CGRectMake(10, 10, 20, 20);

aview = [[UIView alloc] initWithFrame:CGRectMake(0,0, 320, 200)];

NSLog(@"aview retain=%d,image retain=%d",[aview retainCount],[randomImage retainCount]);

[aview addSubview:randomImage];
NSLog(@"aview retain=%d,image retain=%d",[aview retainCount],[randomImage retainCount]);
[randomImage release];
NSLog(@"aview retain=%d,image retain=%d",[aview retainCount],[randomImage retainCount]);


[self.view addSubview:aview];
NSLog(@"aview retain=%d,image retain=%d",[aview retainCount],[randomImage retainCount]);
[aview release];
NSLog(@"aview retain=%d,image retain=%d",[aview retainCount],[randomImage retainCount]);

[aview removeFromSuperview];
NSLog(@"aview retain=%d,image retain=%d",[aview retainCount],[randomImage retainCount]);

控制台日志是這樣的:

 2009-08-09 23:29:42.512 ActionSheetTest[744:20b] aview retain=1,image retain=1
2009-08-09 23:29:42.513 ActionSheetTest[744:20b] aview retain=1,image retain=2
2009-08-09 23:29:42.515 ActionSheetTest[744:20b] aview retain=1,image retain=1
2009-08-09 23:29:42.516 ActionSheetTest[744:20b] aview retain=2,image retain=1
2009-08-09 23:29:42.517 ActionSheetTest[744:20b] aview retain=1,image retain=1

實際上,在最后一個NSLog中,應用程序將崩潰,因為這兩個對象都具有keepCount = 0。

希望這可以幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM