2017-06-22 14 views
5

Ứng dụng của tôi không phải lúc nào cũng chuyển sang bộ điều khiển chế độ xem tiếp theo khi được gọi là performSegue. Tuy nhiên, nó luôn luôn thực hiện prepare(for:sender)ngay lập tức.performSegue không phải lúc nào cũng chuyển đổi, nhưng chuẩn bị (cho: người gửi) luôn được gọi là

  • Lý do gì khiến cho performSegue không hoạt động mà không gặp lỗi nghiêm trọng (và vẫn thực thi prepareForSegue)?
  • Có trạng thái nào đó mà trình điều khiển xem nguồn được cho là ở trong đó tôi cần kiểm tra không?
  • Nếu tôi đặt trễ 10 giây (thông qua asyncAfter), sự phân biệt xảy ra.

Kịch bản

Tôi cố gắng để tái mục đích một segue làm việc cho một tính năng mới (tích hợp để tìm kiếm Spotlight.) Việc chuyển đổi không xảy ra trên iPhone của tôi nếu ứng dụng còn lại trên chi tiết lượt xem. (Ứng dụng này có một UISplitViewController như điều khiển xem gốc của nó.)

Tuy nhiên, mã hoạt động như mong đợi khi

  1. tôi thử nghiệm trên iPad của tôi - tức là, khi xem cả tổng thể và chi tiết đang được hiển thị.
  2. Tôi thử nghiệm trên iPhone của mình khi tôi rời khỏi ứng dụng trên chế độ xem chính.

Khi tôi kiểm tra iPhone của tôi từ màn hình chi tiết {xem code dưới đây}:

  1. Màn hình chi tiết sẽ biến mất (theo popToRootViewController)
  2. Quan điểm tổng thể được hiển thị, với hàng đúng nhấn mạnh (bao gồm cả NSLog nói "Into the master")
  3. Hàm thực thi, bao gồm cả prepare(for:sender) nhưng chế độ xem chi tiết không bao giờ được hiển thị.

Tại thời điểm này, tôi có thể nhấn vào hàng thích hợp và khoảng cách xảy ra như mong đợi - đó là tableView(:didSelectRowAt:) gọi performSegue.

Ngay cả thêm chi tiết

Swift 3.0 & iOS 10

Ứng dụng này có một UISplitViewController như rootViewController của nó. Chế độ xem chính là một tableView với một danh sách các công thức nấu ăn. Khung nhìn chi tiết là một tableView liệt kê các thành phần cho công thức đã chọn. Sự chuyển đổi segue từ lựa chọn hàng công thức thành bảng thành phần của nó.

Tôi đang đưa vào một tính năng mới: đưa công thức vào Spotlight, để người dùng có thể tìm kiếm chúng và khi được chọn, công thức được chọn từ chế độ xem chính và các thành phần của nó được hiển thị trong chế độ xem chi tiết.

Bây giờ tôi đang cố gắng để thực hiện việc tích hợp tìm kiếm Spotlight qua application(:continue:restorationHandler) của appdelegate:

func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([Any]?) -> Void) -> Bool { 

    guard userActivity.activityType == CSSearchableItemActionType, 
    let userInfo = userActivity.userInfo, 
    let id = userInfo[CSSearchableItemActivityIdentifier] as? String 
     else { 
      return false 
    } 

    // The id is a unique identifier for recipe. 
    if let inputRecipe = Recipe.getBy(uuid: id, moc: self.managedObjectContext) { 

     let root = self.window?.rootViewController as! UISplitViewController 
     let nav = root.viewControllers[0] as! UINavigationController 

     // If this is a navigation controller, then detail is being shown 
     if (nav.topViewController as? UINavigationController) != nil { 
      NSLog("Should be a detail view") 
      nav.popToRootViewController(animated: true) 
     } 

     if let masterVC = nav.topViewController as? RecipeMasterVC { 
      NSLog("Into the master") 
      masterVC.selectTableRowAt(recipe: inputRecipe) 
     } 
    } 
    return true 
} 

Trong RecipeMasterVC, tôi đã thêm mã này vào Segue

func selectTableRowAt(recipe: Recipe){ 

    let indexPath = self.fetchedResultsController.indexPath(forObject: recipe) 

    self.tableView.selectRow(at: indexPath, animated: true, scrollPosition: .top) 
    DispatchQueue.main.async { 
     self.performSegue(withIdentifier: seguesEnum.RecipeDetail.rawValue, sender: recipe) 
    } 
} 
+0

Trình điều khiển chế độ xem chính có thể chưa được tải. Nó là hoàn toàn có thể cho bộ điều khiển xem tồn tại - đó là init() đã được gọi để bộ điều khiển xem phân tách tham chiếu nó, nhưng viewDidLoad() chưa được gọi. Hãy thử thêm một số mã gỡ lỗi trong viewDidLoad() hoặc kiểm tra phương thức isViewLoaded bên trong selectTableRow để theo dõi khi chế độ xem chính thực sự được tải. – Dale

+0

@Dale - Ngay trước 'Dispatch {performSegue}', giá trị của 'self.isViewLoaded' là đúng. – AgRizzo

+0

Tôi có một kịch bản tương tự trong ứng dụng của riêng mình, không sử dụng phân đoạn nhưng vẫn sử dụng chế độ xem chia tách. Khi tôi kiểm tra mã tôi thấy rằng tôi đã phải thêm một sự chậm trễ 200ms để làm cho nó hoạt động. Không bao giờ có được nguyên nhân gốc rễ, nhưng không có sự chậm trễ, ngay cả với một công văn async không hoạt động nếu màn hình chi tiết đã được hiển thị – Dale

Trả lời

3

Tôi có một kịch bản tương tự trong tôi ứng dụng riêng, không sử dụng phân đoạn nhưng vẫn sử dụng chế độ xem chia tách. Khi tôi kiểm tra mã tôi thấy rằng tôi đã phải thêm một sự chậm trễ 200ms để làm cho nó hoạt động. Không bao giờ đạt được nguyên nhân gốc rễ, nhưng không chậm trễ, ngay cả khi công cụ async không hoạt động nếu màn hình chi tiết đã được hiển thị

Các vấn đề liên quan