Phân vùng thích ứng trong Xcode bảng phân cảnh 6. Đẩy có bị ngừng sử dụng không?


121

Trình tạo giao diện Xcode 6 theo mặc định có hộp kiểm mới "sử dụng các lớp kích thước". Nó làm cho các quan điểm trở nên thích ứng. nhập mô tả hình ảnh ở đây

Khi tôi cố gắng phân biệt giữa 2 chế độ xem trong bảng phân cảnh của mình, tôi có các tùy chọn mới: nhập mô tả hình ảnh ở đây

thay vì cũ:

nhập mô tả hình ảnh ở đây

Bây giờ chúng ta có "show" và "hiện tại theo phương thức" thay vì "đẩy" và "phương thức". Các tùy chọn cũ được đánh dấu là không dùng nữa. Tôi đã chọn tùy chọn "hiển thị", bởi vì trong cài đặt xác định nó được gọi là "hiển thị (ví dụ: đẩy)

nhập mô tả hình ảnh ở đây

Nhưng nó không tạo ra sự thúc đẩy. Hoạt ảnh Segue trông giống như trượt từ dưới cùng (phương thức) và thanh điều hướng biến mất.

Câu hỏi đặt ra là: Làm thế nào tôi có thể làm cho "chương trình" hoạt động như push? Có thể hay tôi nên sử dụng "push (không được dùng)" để thay thế? Tôi có thể tìm bất kỳ thông tin nào về các loại segue mới ở đâu? Điều duy nhất tôi tìm thấy trong thư viện nhà phát triển iOS8 là Bảng phân cảnh giúp bạn thiết kế giao diện người dùng của mình nhưng không có thông tin về segue "hiển thị".

CẬP NHẬT

Tôi đã cố gắng tạo dự án mới và "show" thực sự hoạt động giống như "push". Tôi nghĩ rằng vấn đề trong dự án của mình có thể là do tôi sử dụng lại bộ điều khiển điều hướng với mã như thế này, nhưng tôi không biết cách khắc phục.

if ( [segue isKindOfClass: [SWRevealViewControllerSegue class]] ) {
    SWRevealViewControllerSegue *swSegue = (SWRevealViewControllerSegue*) segue;
    
    swSegue.performBlock = ^(SWRevealViewControllerSegue* rvc_segue, UIViewController* svc, UIViewController* dvc) {
        
        UINavigationController* navController = (UINavigationController*)self.revealViewController.frontViewController;
        [navController setViewControllers: @[dvc] animated: NO ];
        [self.revealViewController setFrontViewPosition: FrontViewPositionLeft animated: YES];
    };
    
}

Sau đó, tôi cố gắng đẩy NewViewController sau MainViewController nhập mô tả hình ảnh ở đây

CẬP NHẬT 2:

Tôi dường như chỉ gặp vấn đề về iOS 7, iOS 7.1.

Câu trả lời:


97

Có, sử dụng 'Hiển thị' thay vì 'Đẩy'

Làm thế nào tôi có thể làm cho "chương trình" hoạt động như đẩy? Có thể hay tôi nên sử dụng "push (depricated)" để thay thế?

Nó nên; nó làm cho tôi. Tôi đang sử dụng Xcode 6 beta 2 và để kiểm tra, tôi đã sử dụng mẫu chế độ xem đơn (gọi bộ điều khiển chế độ xem được tạo sẵn trong IB 'VC_A'). Sau đó, tôi đã thêm một bộ điều khiển chế độ xem khác ('VC_B'). Sau đó, tôi đã thêm một nút trên VC_A để hiển thị VC_B và một nút khác từ VC_B trở lại VC_A. Khi tôi thêm bộ điều khiển điều hướng làm bộ điều khiển chế độ xem ban đầu trong bảng phân cảnh và đặt VC_A làm rootViewController, cả 'push' và 'show' đều có cùng tác dụng. Nếu tôi không có bộ điều khiển điều hướng ban đầu và tôi sử dụng 'show', tôi nhận được những gì bạn mô tả trong đó VC_B trượt lên từ dưới cùng. Nếu tôi cố gắng 'đẩy', tôi sẽ gặp sự cố vì để thực hiện đẩy, tôi phải có bộ điều khiển điều hướng.

Tôi có thể tìm bất kỳ thông tin nào về các loại segue mới ở đâu?

Vì vậy, tôi đã tìm thấy một số thông tin trong phiên 'Có gì mới trong trình tạo giao diện' tại đây . Nếu bạn nhìn vào các slide, bạn sẽ thấy một slide (41) đề cập đến sự thay đổi. Khi xem video phiên đó, bạn có thể bỏ qua đến phút 38:00, nơi họ bắt đầu nói về các dòng thích ứng. Họ giải thích rằng, ví dụ: segue thích ứng 'hiển thị' sẽ tính đến ngữ cảnh khi quyết định cách thực hiện việc trình bày bộ điều khiển chế độ xem mới.


Cảm ơn bạn vì câu trả lời. Tôi đã cố gắng tạo dự án mới và "chương trình" thực sự hoạt động giống như đẩy với bộ điều khiển điều hướng. Trong dự án của tôi, tôi có cấu trúc phức tạp với sidebar từ bài học này appcoda.com/ios-programming-sidebar-navigation-menu và push hoạt động, hiển thị thì không. Có thể là lý do tôi sử dụng lại bộ điều khiển điều hướng. Tôi đã cập nhật câu hỏi của mình với mã sử dụng lại.
John Kakon

Vì vậy, điều đầu tiên tôi thấy khi xem bản cập nhật của bạn là bạn đang sử dụng mong đợi segue tùy chỉnh: 'SWRevealViewControllerSegue', vì vậy, có lẽ không hợp lý khi sử dụng 'show' hoặc 'push' trong trường hợp của bạn vì chúng được tích hợp sẵn segues trong khi bạn muốn chạy mã tùy chỉnh của riêng mình. Khi tôi tải xuống dự án mẫu, nó thậm chí còn hiển thị lựa chọn 'tùy chỉnh' trên các segues trong tệp bảng phân cảnh.
Spencer Hall

Ý tôi không phải là gã đàn ông này. Tôi đã nói về việc tạo UIViewController mới bên cạnh "MainViewController" (nó có Bộ điều khiển điều hướng và "bản cập nhật" của tôi chỉ hiển thị cách tôi đến đó) và cố gắng đẩy Chế độ xem mới vào MainViewController. Ảnh chụp màn hình của Storyboard Tôi sẽ rất biết ơn nếu bạn bật "sử dụng các lớp kích thước" trong dự án mẫu, tạo NewViewController và thử tạo sự phân biệt giữa MainViewController và NewViewController bằng "show". Bạn sẽ thấy những gì tôi đang nói về.
John Kakon

Điều đó vừa rồi và ít nhất đối với tôi "chương trình" hoạt động giống như "đẩy".
Spencer Hall

9
Bạn có thể khắc phục lỗi bằng cách đảm bảo rằng tất cả các cách vào bộ điều khiển chế độ xem của bạn đều có UINavigationController ở gốc. Ngay cả khi điều đó có nghĩa là đưa UINavigationController vào bảng phân cảnh của bạn sẽ không bao giờ được truy cập. Có vẻ như hệ thống dây được sử dụng để suy ra hành vi.
Scott Robertson

33

Đã có một câu trả lời được chấp nhận, nhưng tôi muốn cung cấp thêm một chút thông tin, có thể là thông tin chưa có trước đây.

Như đã đề cập trước đây, các segues "push" và "modal" không được dùng nữa và đã được thay thế bằng "show" và "present modally". Theo tài liệu của Apple, các phân đội mới đã được chia thành các phân đội thích ứng với các loại kích thước. Các phiên bản cũ hơn chỉ nên được sử dụng để hỗ trợ các phiên bản iOS cũ hơn iOS 8.

Tài liệu trong liên kết sau giải thích điều đó và mô tả tất cả các segues có sẵn, cũ và mới.

Thêm phân biệt giữa các cảnh trong một bảng phân cảnh

Trong trường hợp URL thay đổi trong tương lai, đây là lời giải thích cho từng phân đoạn mới:

Chỉ

Trình bày nội dung trong vùng chi tiết hoặc tổng thể tùy thuộc vào nội dung của màn hình. Nếu ứng dụng đang hiển thị chế độ xem chính và chi tiết, nội dung sẽ được đẩy lên vùng chi tiết. Nếu ứng dụng chỉ hiển thị chính hoặc chi tiết, nội dung sẽ được đẩy lên trên ngăn xếp bộ điều khiển chế độ xem hiện tại.

Hiển thị chi tiết

Trình bày nội dung trong khu vực chi tiết. Nếu ứng dụng đang hiển thị chế độ xem chính và chi tiết, nội dung mới sẽ thay thế chi tiết hiện tại. Nếu ứng dụng chỉ hiển thị chính hoặc chi tiết, nội dung sẽ thay thế phần trên cùng của ngăn xếp bộ điều khiển chế độ xem hiện tại.

Trình bày một cách vừa phải

Trình bày nội dung một cách tiết chế. Có các tùy chọn để chọn kiểu trình bày (UIModalPresentationStyle) và kiểu chuyển tiếp (UIModalTransitionStyle).

Trình bày dưới dạng Popover

Trình bày nội dung dưới dạng một cửa sổ bật lên được neo vào một chế độ xem hiện có. Có một tùy chọn để chỉ định các hướng có thể có của mũi tên được hiển thị trên một cạnh của chế độ xem cửa sổ bật lên (UIPopoverArrowDirection). Ngoài ra còn có một tùy chọn để chỉ định chế độ xem neo.


24

tldr; Xóa Segue không đẩy đúng cách và tạo lại nó trong bảng phân cảnh bằng cách kéo từ UIView / UIControl vào bộ điều khiển chế độ xem mục tiêu.

Không có gì sai với các câu trả lời khác nhưng câu trả lời này giải thích điều gì đang xảy ra, cách bạn có thể xác minh rằng điều đó đang xảy ra và cách giảm thiểu vấn đề trong tương lai.

Lý lịch

Trong trường hợp của tôi, không có Show Segues nào của tôi đang hoạt động mặc dù tôi đã có UINavigationController làm bộ điều khiển chế độ xem ban đầu (với UIViewController nội dung của tôi là root).

Tại sao và Làm thế nào Hiển thị Segue Breaks

Show segue bị phá vỡ khi nó có một hành động được liên kết với segue trong xml nguồn của bảng phân cảnh. Một trường hợp điển hình gây ra điều này có thể là nếu bạn đã xác định lại một vùng từ một vùng thủ công được gọi trước đó trong mã. Điều này để lại các bit sau trong xml bảng phân cảnh.

<connections>
    <segue destination="85t-Z1-hxf" kind="show" identifier="ToOptions" action="showDetailViewController:sender:" id="gdZ-IX-KcN">
</connections>

Nota Bene Để xem bảng phân cảnh dưới dạng xml; Nhấp chuột phải vào tệp bảng phân cảnh và chọn Mở dưới dạng> Mã nguồn . Để hoàn nguyên, hãy sử dụng Mở dưới dạng> Trình tạo giao diện - Bảng phân cảnh

Để đáp ứng bất kỳ hành động tùy chỉnh nào khi sử dụng segue từ bảng phân cảnh, người ta có thể chỉ cần nhấn vào readyForSegue và chặn bộ điều khiển chế độ xem đích và gọi bất kỳ phương thức nào từ vị trí đó. Trong mọi trường hợp, tác dụng phụ đối với lỗi nhỏ này (lỗi là thực tế là khi bạn xác định lại cấu trúc, nó không được thiết lập đúng cách trong xml ~ tức là hành động vẫn còn ngay cả sau khi bạn thay đổi cấu hình thành một hoạt động từ UIView (hoặc UIControl) tới bộ điều khiển chế độ xem mục tiêu).

Thật không may, giải pháp trực tiếp nhất không thành công. Vì vậy, chỉ xóa thuộc tính xml cho hành động từ bên trong Bảng phân cảnh sẽ KHÔNG khắc phục được sự cố. Thay vào đó, người ta chỉ cần xóa và tạo lại segue trong bảng phân cảnh.

Khi được tạo lại, xml của bảng phân cảnh sẽ không còn tác vụ được liên kết với segue cụ thể nữa và Chương trình sẽ thực thi dưới dạng Đẩy.

Xml mẫu cho đúng Show Segue

  <connections>
    <segue destination="RbV-Au-WV9" kind="show" identifier="ToOptions" id="5dm-os-bcS"/>
  </connections>

Giảm nhẹ

Để ngăn sự tái diễn, người ta chỉ cần bám vào các phần đầu của bảng phân cảnh không thủ công nếu có thể bằng cách sử dụng standardForSegue để thêm các hành động cần thiết dựa trên bộ điều khiển chế độ xem đích. Hoặc nếu bạn phải kết hợp và kết hợp, hãy thận trọng để xác minh rằng các segues Show của bạn không có bất kỳ hành động nào được đính kèm trong xml bảng phân cảnh. Nếu bạn đang xử lý các dự án cũ thì bạn nên chú ý đặc biệt đến mã nguồn Storyboard vì tôi đã phát hiện ra một số vấn đề.


3
Sau nhiều giờ, điều này có lẽ đã tiết kiệm cho tôi một số giờ khác. Đây là những gì tôi sẽ đề xuất dựa trên những điều trên: Mở bảng phân cảnh dưới dạng Mã nguồn , tìm kiếm kind = "show" và xem dòng có chứa nội dung như action = "showDetailViewController: sender:" hay không , nếu có, hãy xóa mọi thứ khỏi hành động = cho đến khi kết thúc " . Tôi có một bảng phân cảnh thực rất lớn và dòng bị ảnh hưởng không chứa thông số hành động này nhưng một dòng không liên quan khác thì có. Sau khi tôi xóa hành động, tất cả các chuỗi thích ứng đã hoạt động trở lại như mong đợi. Chỉ cần xóa nhóm bị ảnh hưởng thì không ' t làm việc.
Marcus

Điều này cũng đã cứu tôi.
Adam Bardon

1
Xóa thuộc tính hành động trong XML đã làm việc cho bạn của tôi.
Brent Royal-Gordon

cũng đã cứu tôi
Jimmy George Thomas.

Đã xóa thuộc tính hành động trong tệp xml và thì đấy, nó hoạt động. Sẽ không bao giờ tìm thấy vấn đề nếu không có bài đăng này.
krizzzn

20

Như Scott Robertson đã nhận xét ở đây , đây giống như một lỗi trong iOS 7.

Có vẻ như trong iOS 8, quá trình chuyển đổi được suy ra trong thời gian chạy (hành vi chính xác), trong khi trong iOS 7, quá trình chuyển đổi được suy ra tại thời điểm thiết kế (hành vi lỗi).

Cách giải quyết đơn giản nhất là thêm bộ điều khiển điều hướng không sử dụng vào bảng phân cảnh và liên kết nó với bộ điều khiển chế độ xem được đề cập là một phần của bộ điều khiển điều hướng này. Bạn không thực sự phải khởi tạo bộ điều khiển điều hướng, bạn chỉ cần bộ điều khiển chế độ xem lỗi để biết nó được nhúng trong bộ điều khiển điều hướng.

Lưu ý: Việc mô phỏng thanh điều hướng là không đủ cho những mục đích này; bạn thực sự phải có một bộ điều khiển điều hướng trong ngăn xếp đẩy của nó.

Để tái tạo lỗi:

  1. Tạo một bảng phân cảnh mới sử dụng các lớp kích thước.
  2. Tạo bộ điều khiển hai chế độ xem (không có bộ điều khiển điều hướng).
  3. Làm cho bộ điều khiển chế độ xem thứ nhất hiển thị bộ điều khiển chế độ xem thứ hai thông qua một segue Show (ví dụ: Đẩy) được liên kết với một nút chẳng hạn.
  4. Trong mã, hiển thị bộ điều khiển chế độ xem đầu tiên, nhưng nhúng nó vào bộ điều khiển điều hướng thông qua initWithRootViewController:phương thức.
  5. Chạy ứng dụng trên iOS 7.
  6. Nhấn vào nút sẽ thực hiện ấn.
  7. Bạn sẽ nhận được một chuyển đổi phương thức thay vì đẩy trên iOS 7. Trên iOS 8, bạn sẽ nhận được hành vi đẩy, chính xác.

nhập mô tả hình ảnh ở đây

Để sửa lỗi:

  1. Thêm bộ điều khiển điều hướng vào bảng phân cảnh và đặt bộ điều khiển chế độ xem đầu tiên làm bộ điều khiển chế độ xem gốc. (Lưu ý: thêm thứ hai làm bộ điều khiển chế độ xem gốc sẽ KHÔNG sửa được lỗi này.)
  2. Cung cấp cho nó một số nhận dạng rác để ngăn chặn cảnh báo về việc bộ điều khiển điều hướng không thể truy cập được và ghi lại cho bạn rằng nó chỉ tồn tại như một giải pháp thay thế. (vd workaround for show segues in iOS 7).

nhập mô tả hình ảnh ở đây

Lưu ý cách bộ điều khiển điều hướng được thêm vào trong hình thứ hai và cách nó không có bất kỳ mũi tên nào đến (tức là không có cách nào để khởi tạo nó ngoài việc sử dụng bộ nhận dạng bộ điều khiển chế độ xem).


1
Cảm ơn, lừa với NavigationController đã làm nó cho tôi khi im Trao đổi gốc rễ NavigationControllers ViewController-Stack
Peter Pint

1
Giải pháp tốt nhất. Cảm ơn
Илья Голованов

13

Tôi biết mình đã muộn nhưng tôi muốn chia sẻ những gì tôi học được. Đây thực chất là một lỗi và vẫn còn tồn tại cho đến ngày nay (2014-12-18).

Tôi đã viết một bài báo về điều này ở đây .

Nó có thể dễ dàng tái sản xuất; trên iOS8 sẽ hoạt động tốt và ngay cả trong iOS7.x miễn là bạn không đẩy bộ điều khiển chế độ xem theo lập trình vào ngăn xếp trước khi gọi Showsegue.

Nếu bạn chỉ đẩy lên ngăn xếp bằng các kết nối bảng phân cảnh, nó sẽ hoạt động; nhưng rõ ràng nếu bạn đẩy qua mã bằng cách nào đó thì thuộc navigationControllertính của mã được đẩy UIViewControllersẽ là nilvà khi bạn gọi Shownó sẽ coi nó là một phương thức vì không có điều hướng để kiểm soát ngăn xếp.

Chỉ có cách giải quyết cho đến nay là không đẩy qua mã (không khả thi) hoặc sử dụng hiện không dùng nữa Push.

Tôi đã nộp một radar (liên kết trên bài báo). Vui lòng gửi các bản sao với hy vọng Apple sẽ khắc phục được sự cố này.


3
Đây chính xác là vấn đề của tôi, cảm ơn! sử dụng push không dùng nữa dường như là giải pháp ít tệ hơn trong trường hợp này.
Moshe Gottlieb

Một giải pháp khác là thêm bộ điều khiển điều hướng (không sử dụng) vào bảng phân cảnh. Xem stackoverflow.com/questions/24184003/…
Senseful

Không! Nó đang xảy ra ở đây và nguyên nhân không phải là sự thúc đẩy theo chương trình. Trong trường hợp của tôi, tôi thực hiện một Showsegue, sau đó trên Showsegue thứ hai, nó được trình bày theo cách thức, Giải pháp?
Frade

@Frade bạn có thể liên kết đến một repo github nơi mà nó có thể tái tạo được không? Bạn đang chạy trên phiên bản iOS nào?
esttorhe

dự án riêng .. Nó xảy ra khi cố gắng thực hiện một (thứ hai) Showcủa một viewController trên iOS 7
Frade

2

Tôi đã gặp vấn đề tương tự với các segues trong Xcode 7 và iOS 7.1.2. Show segues (tính năng mới từ iOS 8) hoạt động giống như modal segues trong iOS 7 và không cho phép bạn đẩy View Controllers của mình vào ngăn xếp Navigation Controller khi bạn xác định loại segue bằng Xcode trong Storyboard của mình. Đó là lý do tại sao self.navigationController của bạn sẽ trả về nil, bởi vì View Controller không được đẩy vào ngăn xếp và bạn không thể bật nó lên.

Tôi không hiểu tại sao Apple không thêm bất kỳ thông báo nào cho trường hợp này trong Xcode khi bạn cần ứng dụng của mình hoạt động trên iOS 7. Họ nói rằng phương pháp Đẩy không được chấp nhận, nhưng Hiển thị không hoạt động chính xác với iOS 7.

Tôi đã làm gì để giải quyết vấn đề:

Tôi đã tạo lớp MYShowSegue với .h

#import <UIKit/UIKit.h>

@interface MYShowSegue : UIStoryboardSegue

@end

Và tệp .m chỉ với một phương thức thực hiện :

#import "MYShowSegue.h"

@implementation MYShowSegue

- (void) perform {

    if ([[[self sourceViewController] navigationController] respondsToSelector:@selector(showViewController:sender:)]) {

        id sender = nil;
        [[[self sourceViewController] navigationController] showViewController:[self destinationViewController] sender:sender];
    }else{

        [[[self sourceViewController] navigationController] pushViewController:[self destinationViewController] animated:YES];
    }
}

@end

Ngoài ra, bạn cần phải đặt một loại Tùy chỉnh cho từng phân đoạn trong Bảng phân cảnh của mình và chọn một lớp mới cho nó, trong trường hợp của tôi, đó là MYShowSegue.

Ví dụ về phân đoạn tùy chỉnh

Giải pháp này sẽ giúp bạn hỗ trợ đầy đủ các ứng dụng iOS 7 của mình, chúng sẽ sử dụng phương thức pushViewController để đẩy Lượt xem của bạn và đối với iOS 8,9, v.v. segue của bạn sẽ hoạt động với phương thức mới (iOS 8) showViewController

Đừng quên làm điều tương tự với tất cả các segues trong Bảng phân cảnh của bạn.


Thoải mái giải pháp - làm việc cho tôi (thay vì thêm một "không sử dụng" điều khiển chuyển hướng ...
Laurenz Glück

1

Điều này vẫn xảy ra trong iOS 10.x

Việc xóa và cài đặt lại các segues không giải quyết được gì đối với tôi:

Vấn đề: Chức năng được yêu cầu là 7 segues chỉ hoạt động như một 'push' (thực sự là một chương trình Chi tiết) nhưng trên thực tế chỉ có segue đầu tiên tôi thêm vào sẽ push, các segues khác đều hoạt động theo phương thức. Điều này là mặc dù Trình tạo giao diện mô tả từng dòng giống nhau.

Giải pháp: Tôi đã phải thêm hành động vào 6 segues không có nó.

XML Bảng phân cảnh gốc

<connections>
  <segue destination="tIr-4a-WfZ" kind="showDetail" identifier="A" action="showViewController:sender:" id="8yd-Ne-7KA"/>
  <segue destination="4mB-YE-5dM" kind="showDetail" identifier="B" id="Uod-JC-786"/>
  <segue destination="Qh5-bJ-KcE" kind="showDetail" identifier="C" id="3PW-nV-hWl"/>
  <segue destination="EI6-f4-QBB" kind="showDetail" identifier="D" id="WUK-ju-KDm"/>
  <segue destination="nTz-N4-fpW" kind="showDetail" identifier="E" id="Id6-bW-Huc"/>
  <segue destination="JEp-CH-6dW" kind="showDetail" identifier="F" id="G0L-XW-7f4"/>
  <segue destination="AET-S1-O6h" kind="showDetail" identifier="G" id="3NK-93-wTy"/>
</connections>

Tôi đã thay đổi điều này bằng cách thêm showViewController: sender

<connections>
  <segue destination="tIr-4a-WfZ" kind="showDetail" identifier="A" action="showViewController:sender:" id="8yd-Ne-7KA"/>
  <segue destination="4mB-YE-5dM" kind="showDetail" identifier="B" action="showViewController:sender:" id="Uod-JC-786"/>
  <segue destination="Qh5-bJ-KcE" kind="showDetail" identifier="C" action="showViewController:sender:" id="3PW-nV-hWl"/>
  <segue destination="EI6-f4-QBB" kind="showDetail" identifier="D" action="showViewController:sender:" id="WUK-ju-KDm"/>
  <segue destination="nTz-N4-fpW" kind="showDetail" identifier="E" action="showViewController:sender:" id="Id6-bW-Huc"/>
  <segue destination="JEp-CH-6dW" kind="showDetail" identifier="F" action="showViewController:sender:" id="G0L-XW-7f4"/>
  <segue destination="AET-S1-O6h" kind="showDetail" identifier="G" action="showViewController:sender:" id="3NK-93-wTy"/>
</connections>
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.