2009-08-21 44 views
32

làm thế nào để loại bỏ tất cả subviews từ scrollview của tôi ...cách xóa các bản xem trước khỏi chế độ xem cuộn?

tôi có một UIView và một nút ở trên nó trong một cái gì đó scrollview như thế này ....

đây là mã của tôi để thêm subview trong cuộn xem

-(void)AddOneButton:(NSInteger)myButtonTag { 
lastButtonNumber = lastButtonNumber + 1; 

if ((lastButtonNumber == 1) || ((lastButtonNumber%2) == 1)) { 
btnLeft = 8;} 
else if ((lastButtonNumber == 2) || ((lastButtonNumber%2) == 0)) { 
btnLeft = 162; 
} 
CGRect frame1 = CGRectMake(btnLeft, btnTop, 150, 150); 
CGRect frame2 = CGRectMake(btnLeft, btnTop, 150, 150); 
UIButton *Button = [UIButton buttonWithType:UIButtonTypeCustom]; 
Button.frame = frame1; 
Button.tag = myButtonTag; 
[Button addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchUpInside]; 
[Button setBackgroundColor:[UIColor clearColor]]; 
[Button setBackgroundImage:[UIImage imageNamed:@"WaitScreen.png"] forState:UIControlStateHighlighted]; 

    GraphThumbViewControllerobj = [[GraphThumbViewController alloc] initWithPageNumber:[[GraphIdArray objectAtIndex:myButtonTag]intValue]]; 
    GraphThumbViewControllerobj.view.frame=frame2; 
    GraphThumbViewControllerobj.lblCounter.text=[NSString stringWithFormat:@"%d of %d",myButtonTag+1,flashCardsId.count]; 
    GraphThumbViewControllerobj.lblQuestion.text=[flashCardText objectAtIndex:myButtonTag]; 
    [myScrollView addSubview:GraphThumbViewControllerobj.view]; 


[myScrollView addSubview:Button]; 


if ((lastButtonNumber == 2) || ((lastButtonNumber%2) == 0)) { 
btnTop = btnTop + 162; 
} 
if (btnTop+150 > myScrollView.frame.size.height) { 
myScrollView.contentSize = CGSizeMake((myScrollView.frame.size.width), (btnTop+160));} 
} 

và đây là mã để loại bỏ subviews

if(myScrollView!=nil) 
{ 
     while ([myScrollView.subviews count] > 0) { 
      //NSLog(@"subviews Count=%d",[[myScrollView subviews]count]); 
      [[[myScrollView subviews] objectAtIndex:0] removeFromSuperview]; 
} 

alt text http://www.freeimagehosting.net/uploads/e5339a1f51.png

Trả lời

102

Để loại bỏ tất cả các subviews từ bất kỳ quan điểm, bạn có thể lặp qua các subviews và gửi mỗi một cuộc gọi removeFromSuperview:

// With some valid UIView *view: 
for(UIView *subview in [view subviews]) { 
    [subview removeFromSuperview]; 
}

này là hoàn toàn vô điều kiện, tuy nhiên, và sẽ thoát khỏi tất cả subviews trong khung nhìn đã cho. Nếu bạn muốn một cái gì đó hạt mịn hơn, bạn có thể thực hiện bất kỳ phương pháp khác nhau:

  • Duy trì mảng riêng của bạn về quan điểm của các loại khác nhau, do đó bạn có thể gửi chúng removeFromSuperview thông điệp sau đó theo cách tương tự
  • Giữ lại tất cả các chế độ xem nơi bạn tạo và giữ các con trỏ đến các chế độ xem đó, vì vậy, bạn có thể gửi cho chúng removeFromSuperview riêng lẻ khi cần
  • Thêm câu hỏi if vào vòng trên, kiểm tra bình đẳng của lớp. Ví dụ, để chỉ loại bỏ tất cả các UIButtons (hoặc lớp con tùy chỉnh của UIButton) mà tồn tại trong một cái nhìn, bạn có thể sử dụng một cái gì đó như:
// Again, valid UIView *view: 
for(UIView *subview in [view subviews]) { 
    if([subview isKindOfClass:[UIButton class]]) { 
     [subview removeFromSuperview]; 
    } else { 
     // Do nothing - not a UIButton or subclass instance 
    } 
}
+0

Đây là sự giúp đỡ to lớn đối với tôi. Cảm ơn! –

+1

Đẹp một người bạn đời. Chính xác những gì tôi cần. – Critter

9

Để thêm vào những gì Tim nói, tôi nhận thấy rằng bạn đang gắn thẻ quan điểm của bạn. Nếu bạn muốn xóa chế độ xem bằng một thẻ nhất định, bạn có thể sử dụng:

[[myScrollView viewWithTag:myButtonTag] removeFromSuperview]; 
8

Tôi không nghĩ bạn nên sử dụng đề xuất liệt kê nhanh.

for(UIView *subview in [view subviews]) { 
    [subview removeFromSuperview]; 
} 

Đây không phải là trường hợp ngoại lệ nếu bạn thay đổi bộ sưu tập đang được lặp lại? http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocFastEnumeration.html#//apple_ref/doc/uid/TP30001163-CH18-SW3

Ví dụ này có thể tốt hơn.

NSArray *subviews = [[scroller subviews] copy]; 
for (UIView *subview in subviews) { 
    [subview removeFromSuperview]; 
} 
[subviews release]; 
+0

Điều đó hoạt động hoàn hảo, thankz –

37

Câu hỏi cũ; nhưng vì nó là hit đầu tiên trên Google cho điều này tôi nghĩ rằng tôi cũng muốn làm cho một lưu ý rằng có cũng phương pháp này:

[[myScrollView subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)]; 

Bạn không thể làm các isKindOfClass kiểm tra với điều này, nhưng nó vẫn là một giải pháp tốt để biết về.

Chỉnh sửa: Một điểm cần lưu ý khác là thanh cuộn của chế độ xem cuộn được thêm làm chế độ xem phụ cho cuộn xem đó. Vì vậy, nếu bạn lặp qua tất cả các bản xem trước của một scrollview bạn sẽ đi qua nó. Nếu bị xóa, nó sẽ tự thêm lại - nhưng điều quan trọng là phải biết điều này nếu bạn chỉ mong đợi các lớp con UIView của riêng bạn ở trong đó.

Sửa đổi bổ sung Swift 3:

myScrollView.subviews.forEach { $0.removeFromSuperview() } 
+0

cảm ơn thông tin. –

+0

bạn sở hữu ittt !!!!!!!! –

2

Vấn đề với UIScrollView và những người khác lớp con của UIView là họ chứa ban đầu một số quan điểm (như thanh cuộn dọc và ngang cho UIScrollView). Vì vậy, tôi tạo ra một thể loại của UIView để xóa các Subviews lọc trên lớp.

Ví dụ:

[UIScrollView removeAllSubviewsOfClass:[FooView class],[BarView class],nil]; 

Mã:

- (void)removeAllSubviewsOfClass:(Class)firstClass, ... NS_REQUIRES_NIL_TERMINATION; 


- (void)removeAllSubviewsOfClass:(Class)firstClass, ... 
{ 
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"FALSEPREDICATE"]; 

    va_list args; 
    va_start(args, firstClass); 

    for (Class class = firstClass; class != nil; class = va_arg(args, Class)) 
    { 
     predicate = [NSCompoundPredicate orPredicateWithSubpredicates:[NSArray arrayWithObjects:predicate,[NSPredicate predicateWithFormat:@"self isKindOfClass:%@",class], nil]]; 
    } 

    va_end(args); 
    [[self.subviews filteredArrayUsingPredicate:predicate] makeObjectsPerformSelector:@selector(removeFromSuperview)]; 

} 
0

Cách đơn giản nhất và tốt nhất là

for(UIView *subview in [scrollView subviews]) { 

    [subview removeFromSuperview]; 

} 
1

tốt nhất và đơn giản nhất là sử dụng

for(UIView *subview in [scrollView subviews]) 
{ 
    [subview removeFromSuperview]; 
} 

này thực sự gây ra vụ tai nạn là nguyên tắc cơ bản là mảng không nên sửa đổi trong khi được liệt kê, để ngăn chặn điều đó chúng ta có thể sử dụng

[[scrollView subviews] 
      makeObjectsPerformSelector:@selector(removeFromSuperview)]; 

Nhưng đôi khi vụ tai nạn vẫn xuất hiện bởi vì makeObjectsPerformSelector: sẽ liệt kê và thực hiện chọn, Cũng trong hoạt động iOS 7 ui được tối ưu hóa để thực hiện nhanh hơn trong iOS 6, Do đó cách tốt nhất để lặp mảng reversely và loại bỏ

NSArray *vs=[scrollView subviews]; 
for(int i=vs.count-1;i>=0;i--) 
{ 
    [((UIView*)[vs objectAtIndex:i]) removeFromSuperview]; 
} 

Lưu ý: tác hại liệt kê sửa đổi nhưng không lặp lại ...

0
for(subview) in self.scrollView.subviews { 
     subview.removeFromSuperview() 
} 
Các vấn đề liên quan