#ios #swift #xcode #segue
Вопрос:
Я читал, как кто-то писал метод performSegue в такой функции, как эта:
func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
guard let annotation = mapView.selectedAnnotations.first else {return}
selectedRestaurant = annotation as? RestaurantItem
self.performSegue(withIdentifier: Segue.showDetail.rawValue, sender: self)
}
Мой вопрос в том, что из других книг, которые я читал, включая руководство Apple по XCode 12, я бы подумал написать что-то подобное.
performSegue(withIdentifier: showDetail, sender: nil)
Я не могу понять смысл/значение добавления self
» до performSegue
» и «после sender:
«, поскольку они выглядят излишними.
Аналогично, я бы просто написал в showDetail
качестве идентификатора Segue. Для чего Segue.
.rawValue
нужны » до » и «после showDetail
«? Кажется, я не нахожу никого, кто бы учил людей писать таким образом.
Может быть, это какой-то устаревший способ написания сегментов, когда я читаю книги, написанные в 2020 и/или 2021 годах?
Спасибо…!
Комментарии:
1. Вы можете опустить
self.
это, если хотите.self.
необходимо только внутри закрытия или когда у вас есть 2 переменные с одинаковым именем2.
sender: self
это потому, что «Объект, который вы хотите использовать для инициирования перехода. Этот объект предоставляется в информационных целях во время фактического этапа.» Документация3. «Этот объект предоставляется в информационных целях во время фактического перехода». < — по сути, звучит так, как будто он не нужен и может также использоваться
sender: nil
на практике???
Ответ №1:
sender
Параметр является произвольным и задан по соображениям совместимости с prepare(for segue:sender:)
методом.
В жестко запрограммированном сегменте sender
это либо UITableViewCell
то, либо UIViewController
другое, в зависимости от соединения.
Внутрь performSegue(withIdentifier:sender
вы можете пройти все, что захотите. Если вам не нужен sender
пропуск nil
, но вы можете даже пройти annotation
его, чтобы избавиться от временного имущества.
Что касается идентификаторов, то типобезопасным и более сложным способом обработки идентификаторов является, например, протокол
protocol SegueHandlerType {
associatedtype SegueIdentifier : RawRepresentable
}
и расширение, которое перегружает performSegue(withIdentifier:sender:
метод
extension SegueHandlerType where Self : UIViewController, SegueIdentifier.RawValue == String {
func performSegue(withIdentifier segueIdentifier : SegueIdentifier, sender: Any?) {
performSegue(withIdentifier: segueIdentifier.rawValue, sender:sender)
}
func segueIdentifer(for segue : UIStoryboardSegue) -> SegueIdentifier {
guard let identifier = segue.identifier, let segueIdentifier = SegueIdentifier(rawValue: identifier) else {
fatalError("Invalid segue identifier (segue.identifier!)")
}
return segueIdentifier
}
}
Преимущество заключается в том, что идентификаторы являются перечислениями, которые проверяются во время компиляции.
Затем вы можете принять протокол в контроллере представления и объявить
enum SegueIdentifier : String {
case pushDetail = "PushDetail"
}
...
performSegue(withIdentifier: .pushDetail, sender: annotation)
и внутри prepare(for segue
вы можете проверить
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segueIdentifer(for: segue) == .pushDetail {
let annotation = sender as! RestaurantItem
...