2012-07-18 30 views
10

Trong ứng dụng của tôi, tôi đang cố gắng đưa một khung nhìn lên phía trước, sau đó đặt nó trở lại vị trí lớp ban đầu của nó sau này. Mã này nên được khá đơn giản:Sắp xếp lại các bản tóm tắt của UIView

Để đưa subview phía trước (bên trong lớp UIView tùy chỉnh của tôi):

[self.superview bringSubviewToFront:self]; 

dễ dàng. Tôi lưu trữ vị trí z ban đầu trong một biến mẫu được gọi là, bạn đoán nó, zPosition. Vì vậy, dòng trước -bringSubviewToFront: là:

zPosition = [self.superview.subviews indexOfObject:self]; 

Vì vậy, tất cả các mã tôi sử dụng để mang lại subview của tôi để phía trước là:

zPosition = [self.superview.subviews indexOfObject:self]; 
[self.superview bringSubviewToFront:self]; 

này hoạt động như mong muốn. Vấn đề là khi tôi cố gắng đưa subview trở lại nơi nó được. Tôi chỉ đơn giản là làm điều này:

[self.superview exchangeSubviewAtIndex:zPosition withSubviewAtIndex: 
    [self.superview.subviews indexOfObject:self]]; 

Sử dụng mã này, nếu tôi có hai subviews, đây là những gì sẽ xảy ra:

Hãy nói rằng tôi có cái nhìn A và B. xem Xem A là trên quan điểm B. Tôi bấm vào xem B, nó đi ra phía trước. Tôi chạm vào xem B một lần nữa (nó sẽ quay trở lại nơi nó đã được), và không có gì xảy ra, do đó, nó bây giờ trên xem A. Nếu bây giờ tôi nhấn xem A, nó đến phía trước, nhưng khi tôi khai thác nó một lần nữa (vì vậy nó nên quay trở lại vị trí ban đầu của nó z: dưới xem B), tất cả các quan điểm anh chị em của nó biến mất!

Có ai thấy điều gì có thể gây ra sự cố này không?

+0

lẽ bạn có thể bắt đầu với một hình nộm, subview trống trên đầu. Sau đó, bạn trao đổi qua lại với subview đó. Không phải là thanh lịch nhất, tôi biết ... –

Trả lời

11

exchangeSubviewAtIndex cũng có thể đưa chế độ xem trở lại đúng vị trí, nhưng nó cũng sẽ hoán đổi một chế độ xem khác ở trên cùng, không phải là thứ bạn bắt đầu. Bạn có thể cần phải làm một cái gì đó như thế này thay vì exchangeSubviewAtIndex:

[self retain]; 
UIView *superview = self.superview; 
[self removeFromSuperview]; 
[superview insertSubview:self atIndex:zPosition]; 
[self release]; 
+0

gọi '[tự xóaFromSuperview]' kết quả trong 'self' đang dealloc'd bởi vì một khi nó được gỡ bỏ từ superview của nó, không có gì là sở hữu nó nữa. –

+0

Có lẽ bạn có thể ủy quyền điều này cho superview (và/hoặc bộ điều khiển xem phụ trách phân cấp này) thay vào đó? –

+0

Thử tự giữ lại tạm thời. Tôi đã cập nhật câu trả lời của mình. – AW101

9

Không cần phải để loại bỏ từ SuperView:

[self.superview insertSubview:self atIndex:zPosition];

0

Câu hỏi này và câu trả lời là rất hữu ích cho tôi.

Tôi có yêu cầu đặt lớp phủ giữa khung nhìn mà chế độ xem ở trên và bên dưới lớp phủ và tôi muốn giữ cho nó động. Tức là, một chế độ xem có thể cho biết nó bị ẩn hay không.

Tôi đã sử dụng thuật toán sau để sắp xếp lại lượt xem. Nhờ AW101 bên dưới cho "Không cần phải xóa chế độ xem".

Đây là thuật toán của tôi:

- (void) insertOverlay { 

    // Remember above- and belowcounter 
    int belowpos = 0, abovepos = 0; 

    // Controller mainview 
    UIView *mainview = [self currentMainView]; 

    // Iterate all direct mainview subviews 
    for (UIView* view in mainview.subviews) { 
     if ([self isAboveOverlay:view]) { 
      // Re-insert as aboveview 
      [mainview insertSubview:view atIndex:belowpos + (abovepos++)]; 
     } 
     else { 
      // Re-insert as belowview 
      [mainview insertSubview:view atIndex:belowpos++]; 
     } 
    } 

    // Put overlay in between above and below. 
    [mainview insertSubview:_overlay atIndex:belowpos]; 
}