2010-07-23 30 views
12

Tôi có một UIScrollView phân trang trong đó các trang người dùng theo chiều ngang thông qua hình ảnh, như Photos.app của Apple. Điều đó hoạt động, nhưng bây giờ tôi đang cố gắng thêm hỗ trợ xoay.Làm sạch chuyển đổi autorotation trong một phân trang UIScrollView

Tôi đã xoay chế độ xem OK và đã quản lý để đặt khung nội dung Kích thước, giới hạn và khung nhìn của phụ đề chính xác để thích ứng với các hướng khác nhau. Vì vậy, trước và sau khi quay, mọi thứ đều ổn.

Tuy nhiên, bản thân quá trình chuyển đổi rất khó xử. Hình ảnh đầu tiên quay hoàn hảo, như thể trục xoay nằm ở trung tâm chết của hình ảnh (khung cuộn). Hình ảnh thứ hai "đu" vì trục quay ở cùng một vị trí: tâm của hình ảnh đầu tiên. Xa hơn tôi nhận được từ hình ảnh đầu tiên, nhanh hơn "swing".

Tôi có thể che giấu điều này bằng cách phủ UIView mờ đục trước khi xoay và ẩn sau. Nhưng đó là một hack. Phải có một cách thanh lịch để làm điều này ...

Trả lời

38

Thành thật mà nói, tôi không biết bạn đang làm gì, vì bạn chưa cho chúng ta thấy nhiều.

Nhưng!

Tôi đã tạo một dự án mẫu với một vài chế độ xem trong chế độ xem cuộn và hoạt động tốt. Cảm thấy tự do để chọn nó ngoài như bạn muốn. Nó hoạt động bằng cách tạo 5 khung nhìn và thêm chúng vào chế độ xem cuộn. Sau đó, sau khi các lượt xem này được thiết lập lần đầu tiên và mỗi khi ứng dụng quay, nó sẽ gọi phương thức alignSubviews để đặt chúng ở đúng vị trí trang và làm cho chúng có cùng kích thước với chế độ xem cuộn, trong khi cập nhật chế độ xem contentSize của chế độ xem cuộn . Trước khi xoay vòng xảy ra, nó theo dõi xem trang hiện đang xem trang nào và sau đó đặt lại trang đó trong trang đó (vì kích thước trang phải thay đổi).

Download "Rotolling"!

screenshot http://cl.ly/43de79be29c5a03a1775/content

+0

Tuyệt vời ví dụ! Tôi đã không đăng bất kỳ mã nào bởi vì tôi biết rằng những gì tôi đã cần phải được loại bỏ. Các đạo đức của câu chuyện là nếu tôi thấy mình tự thiết lập và đặt lại khung xem tất cả các nơi, tôi đang làm điều đó sai. – alexantd

+0

Tuyệt vời. Chỉ cần làm việc ra khỏi hộp. Cảm ơn. – Gerd

+4

Cảm ơn ví dụ tuyệt vời. Cần thực hiện một bản sửa lỗi để khởi chạy thành công trên iOS 6: [window setRootViewController: viewController]; để áp dụng: phương thức didFinishLaunchingWithOptions. – kaspartus

1

Có vẻ như bạn đang áp dụng phép thuật, cần thiết để có được phiên bản xoay trên màn hình ở đúng nơi, cách sai.

Vì bạn không chia sẻ bất kỳ mã nào, sau đây chỉ là phỏng đoán. Có lẽ, bạn áp dụng một vòng quay và một bản dịch. Âm thanh âm thanh như bạn đang xoay các nội dung của UIScrollView. Nhận được quyền này sẽ rất phức tạp. Thật khó để nói bất cứ điều gì kết thúc mà không có mã, nhưng nếu bạn chỉ có 1 vòng quay và 1 bản dịch, bạn đang làm theo cách sai. Bạn cần dịch chế độ xem hiện tại sang điểm xoay, xoay và dịch ngược lại. Nếu không thì bản dịch sẽ là một phần của vòng quay (do đó là cú swing lớn).

Bạn nên xoay chính bản thân UIScrollView. Nó sẽ luôn ở trong một vị trí xác định (cụ thể là: màn hình) với một trung tâm xác định. Nội dung sau đó sẽ xoay vòng với nó.

7

Tôi lưu ý thông tin bổ sung này cho sau này tham khảo bản thân mình. Tôi đã giải quyết vấn đề này bằng ý tưởng từ giải pháp @jtvandes '. Tuy nhiên, trong trường hợp của tôi, nó là đủ với những triển khai này. Buộc bố cục lại phá vỡ quan điểm của tôi.

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration 
{ 
    currentPageOffset = [hostingScrollView contentOffset].x/[hostingScrollView bounds].size.width; 
} 
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration 
{ 
    // Layout changed instantly at this time. 
    // So we have to force to set offset instantly by setting animation to NO. 
    [hostingScrollView setContentOffset:CGPointMake([hostingScrollView bounds].size.width * currentPageOffset, 0.0f) animated:NO]; 
} 
1

Một giải pháp đơn giản hoạt động tốt là đăng ký thông báo khi contentSize của UIScrollView được thay đổi và sau đó cập nhật contentOffset tại thời điểm đó.

Theo quan điểm phương pháp tải của bạn thêm dòng này:

[self addObserver:theScrollView forKeyPath:@"contentSize" options:0 context:nil]; 

Theo quan điểm phương pháp dỡ của bạn thêm dòng này:

[self removeObserver:self forKeyPath:@"contentSize"]; 

Săn thông báo:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context 
{ 
    theScrollView.contentOffset = page * theScrollView.bounds.width; 
} 
Các vấn đề liên quan