Метод supportedInterfaceOrientations не отменяет какой-либо метод из его суперкласса

В UIViewController этот код:

public override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
    if let mainController = self.mainViewController{
        return mainController.supportedInterfaceOrientations
    }
    return UIInterfaceOrientationMask.all
}

дает ошибку Method doesn't override any method from its superclass

Я использую Xcode 8 beta 4, а цель развертывания iOS - 9.0, а Use Legacy Swift Language Version установлено значение No в Build Settings

Как преобразовать код выше в Swift 3?

Ответ 1

Вот так:

override var supportedInterfaceOrientations : UIInterfaceOrientationMask {

... и остальное, как и у вас.

Общий шаблон

Теперь многие методы Cocoa являются свойствами, поэтому вы реализуете их как переопределенные вычисленные переменные. Таким образом, шаблон для перемещения из семени 3 (или ранее) в семя 4:

  • Измените func на var

  • Удалить ()

  • Измените -> на :

Это работает, потому что вычисленная переменная имеет функцию getter, поэтому функция, которую вы реализовали, просто превращается в функцию getter. И это свойства, доступные только для чтения, поэтому вам не понадобится сеттер.

Аналогично затронутые методы: preferredStatusBarStyle, prefersStatusBarHidden, shouldAutorotate, preferredInterfaceOrientationForPresentation и многие другие. Найдите UIKIT_DEFINE_AS_PROPERTIES в заголовке Objective-C.

Последствия

В долгосрочной перспективе возможны и другие изменения. Например, вы можете добавить сеттер (деление вашей реализации на функции get и set), и таким образом вы можете превратить свою реализацию в фасад для сохраненного свойства. Например:

private var _orientations = UIInterfaceOrientationMask.portrait
override var supportedInterfaceOrientations : UIInterfaceOrientationMask {
    get { return self._orientations }
    set { self._orientations = newValue }
}

Итак, теперь у вашего кода есть способ установить это значение. Если вы возвращаете разные значения в разное время, это может сделать вещи намного чище.

Дополнительные технические примечания

Интересно, что это изменение не оказывает прямого влияния на существующий код Objective-C, потому что в Objective-C объявление нового свойства @property(nonatomic, readonly) UIInterfaceOrientationMask supportedInterfaceOrientations; выполняется тем же способом, что и раньше:

- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskPortrait;
}

Причина в том, что в Objective-C a @property(readonly) является просто обещанием существования соответствующего метода геттера и того, что именно этот метод. Но в Swift способ написать метод getter Objective-C - это свойство, то есть через переменную экземпляра. На изменение кода влияет только код Swift: вы должны переписать свои методы как свойства.