AdaptiveStoryboard/AdaptiveStoryboard/ListTableViewController.swift
/* |
Copyright (C) 2016 Apple Inc. All Rights Reserved. |
See LICENSE.txt for this sample’s licensing information |
Abstract: |
A view controller that shows a list of conversations that can be viewed. |
*/ |
import UIKit |
class ListTableViewController: UITableViewController { |
// MARK: Properties |
var user: User? { |
didSet { |
if isViewLoaded { |
tableView.reloadData() |
} |
} |
} |
static let conversationCellIdentifier = "ConversationCell" |
static let photoCellIdentifier = "PhotoCell" |
// MARK: Initialization |
deinit { |
NotificationCenter.default.removeObserver(self) |
} |
// MARK: View Controller |
override func viewDidLoad() { |
super.viewDidLoad() |
NotificationCenter.default.addObserver(self, selector: #selector(ListTableViewController.showDetailTargetDidChange(_:)), name: NSNotification.Name.UIViewControllerShowDetailTargetDidChange, object: nil) |
} |
override func viewWillAppear(_ animated: Bool) { |
super.viewWillAppear(animated) |
// Deselect any index paths that push when tapped |
for indexPath in tableView.indexPathsForSelectedRows ?? [] { |
let pushes: Bool |
if shouldShowConversationViewForIndexPath(indexPath) { |
pushes = willShowingViewControllerPushWithSender(self) |
} |
else { |
pushes = willShowingDetailViewControllerPushWithSender(self) |
} |
if pushes { |
// If we're pushing for this indexPath, deselect it when we appear. |
tableView.deselectRow(at: indexPath, animated: animated) |
} |
} |
if let visiblePhoto = currentVisibleDetailPhotoWithSender(self) { |
for indexPath in tableView.indexPathsForVisibleRows ?? [] { |
let photo = photoForIndexPath(indexPath) |
if photo == visiblePhoto { |
tableView.selectRow(at: indexPath, animated: true, scrollPosition: .none) |
} |
} |
} |
} |
func showDetailTargetDidChange(_ notification: Notification) { |
/* |
Whenever the target for showDetailViewController: changes, update all |
of our cells (to ensure they have the right accessory type). |
*/ |
for cell in tableView.visibleCells { |
if let indexPath = tableView.indexPath(for: cell) { |
tableView(tableView, willDisplay: cell, forRowAt: indexPath) |
} |
} |
} |
override func containsPhoto(_ photo: Photo) -> Bool { |
return true |
} |
override func prepare(for segue: UIStoryboardSegue, sender: Any?) { |
if let indexPath = tableView.indexPathForSelectedRow, |
let conversation = conversationForIndexPath(indexPath) { |
if segue.identifier == "ShowConversation" { |
// Set up our ConversationViewController to have its conversation and title |
let destination = segue.destination as! ConversationViewController |
destination.conversation = conversation |
destination.title = conversation.name |
} |
else if segue.identifier == "ShowPhoto" { |
// Set up our PhotoViewController to have its photo and title |
let destination = segue.destination as! PhotoViewController |
destination.photo = conversation.photos.last |
destination.title = conversation.name |
} |
} |
if segue.identifier == "ShowAbout" { |
if presentedViewController != nil { |
// Dismiss Profile if visible. |
dismiss(animated: true, completion: nil) |
} |
} |
else if segue.identifier == "ShowProfile" { |
// Set up our ProfileViewController to have its user |
let navigationController = segue.destination as! UINavigationController |
let destination = navigationController.topViewController as! ProfileViewController |
destination.user = user |
// Set self as the presentation controller's delegate so that we can adapt its appearance |
navigationController.popoverPresentationController?.delegate = self |
} |
} |
// MARK: Table View |
func conversationForIndexPath(_ indexPath: IndexPath) -> Conversation? { |
return user?.conversations[(indexPath as NSIndexPath).row] |
} |
func photoForIndexPath(_ indexPath: IndexPath) -> Photo? { |
if shouldShowConversationViewForIndexPath(indexPath) { |
return nil |
} |
else { |
let conversation = conversationForIndexPath(indexPath) |
return conversation?.photos.last |
} |
} |
// Returns whether the conversation at indexPath contains more than one photo. |
func shouldShowConversationViewForIndexPath(_ indexPath: IndexPath) -> Bool { |
let conversation = conversationForIndexPath(indexPath) |
return (conversation?.photos.count ?? 0) > 1 |
} |
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { |
return user?.conversations.count ?? 0 |
} |
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { |
if shouldShowConversationViewForIndexPath(indexPath) { |
return tableView.dequeueReusableCell(withIdentifier: ListTableViewController.conversationCellIdentifier, for: indexPath) |
} |
else { |
return tableView.dequeueReusableCell(withIdentifier: ListTableViewController.photoCellIdentifier, for: indexPath) |
} |
} |
override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { |
// Whether to show the disclosure indicator for this cell. |
let pushes: Bool |
if shouldShowConversationViewForIndexPath(indexPath) { |
// If the conversation corresponding to this row has multiple photos. |
pushes = willShowingViewControllerPushWithSender(self) |
} |
else { |
// If the conversation corresponding to this row has a single photo. |
pushes = willShowingDetailViewControllerPushWithSender(self) |
} |
/* |
Only show a disclosure indicator if selecting this cell will trigger |
a push in the master view controller (the navigation controller above |
ourself). |
*/ |
cell.accessoryType = pushes ? .disclosureIndicator : .none |
let conversation = conversationForIndexPath(indexPath) |
cell.textLabel?.text = conversation?.name ?? "" |
} |
} |
extension ListTableViewController: UIPopoverPresentationControllerDelegate { |
func presentationController(_ presentationController: UIPresentationController, willPresentWithAdaptiveStyle style: UIModalPresentationStyle, transitionCoordinator: UIViewControllerTransitionCoordinator?) { |
guard let presentedNavigationController = presentationController.presentedViewController as? UINavigationController else { return } |
// We want to show the navigation bar if we're presenting in full screen. |
let hidesNavigationBar = style != .fullScreen |
presentedNavigationController.setNavigationBarHidden(hidesNavigationBar, animated: false) |
} |
} |
Copyright © 2016 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2016-09-13