Почему использование UIControlState.normal для сегментированного элемента управления вызывает этот сбой? - PullRequest
0 голосов
/ 31 октября 2018

У меня есть простой UISegmentedControl с двумя сегментами, и я пытаюсь настроить его внешний вид.

Я получаю эту ошибку во время выполнения:

*** Завершение работы приложения из-за необработанного исключения> 'NSInvalidArgumentException', причина: '- [NSNull renderMode]: нераспознанный селектор отправлен в экземпляр 0x112156f08'

@IBOutlet weak var sortController: UISegmentedControl!

override func viewDidLoad() {
    super.viewDidLoad()

    styleSortController()

    // other setup code

}

func styleSortController() {
    let titleAttributes: [String: Any] = [NSForegroundColorAttributeName: UIColor.white, NSFontAttributeName: UIFont(name: "AvenirNext-Demi", size: CGFloat(14.0)) as Any]
    let selectedTitleAttributes: [String: Any] = [NSForegroundColorAttributeName: UIColor.white,
                                                  NSFontAttributeName: UIFont(name: "AvenirNext-DemiBold", size: CGFloat(14.0)) as Any]

    // this line causes it to crash
    sortController.setTitleTextAttributes(titleAttributes, for: UIControlState.normal)

    // but this line works, no problem
    sortController.setTitleTextAttributes(selectedTitleAttributes, for: UIControlState.selected)
}

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

Согласно документации Apple, я должен иметь возможность использовать любые действительные UIControlState, и UIControlState.normal наверняка кажется действительным, поэтому я действительно не понимаю, почему это происходит.

Что эта линия может доставить мне неприятности?

Ответы [ 2 ]

0 голосов
/ 31 октября 2018
let titleAttributes: [String: Any] = [NSForegroundColorAttributeName: UIColor.white, 
                                      NSFontAttributeName: UIFont(name: "AvenirNext-Demi", size: CGFloat(14.0)) as Any]
let selectedTitleAttributes: [String: Any] = [NSForegroundColorAttributeName: UIColor.white,
                                              NSFontAttributeName: UIFont(name: "AvenirNext-DemiBold", size: CGFloat(14.0)) as Any]

Прежде чем сказать, что это проблема UIControlState, вам нужно сделать:

sortController.setTitleTextAttributes(selectedTitleAttributes, for: UIControlState.normal)

Другими словами, используйте тот же рабочий образец (тот, что для .selected)

Это должно привести к той же ошибке сбоя.

Тогда вы обнаружите, что виновником является UIFont(name: "AvenirNext-Demi", size: CGFloat(14.0)), он возвращает ноль.

Таким образом, имя шрифта неверно.

Вы можете перебрать свой шрифт, чтобы перечислить его ( см. Этот связанный вопрос ) и найти правильный. Это «обычный», так что вы можете открыть Font Book.app , найти его и проверить имя сценария Post. Не все шрифты в macOS есть в iOS, но это так.

enter image description here

Вы получите: AvenirNext-Regular , AvenirNext-Medium , AvenirNext-UltraLight , AvenirNext-Italic , AvenirNext-MediumItalic , AvenirNext-UltraLightItalic , AvenirNext-DemiBold , AvenirNext-Bold , AvenirNext-Heavy , 1045 *, * AvenirNext-DemiBoldItalic , AvenirNext-BoldItalic , AvenirNext-HeavyItalic .

Нет AvenirNext-Demi .

Так что используйте тот, который, по вашему мнению, больше соответствует вашим потребностям.

Я рекомендую использовать пользовательский шрифт для установки их на Mac. Таким образом легко получить название постскриптумного шрифта.

0 голосов
/ 31 октября 2018

Первая проблема, которую я вижу, состоит в том, что большая часть написанного вами кода была переименована в Swift 4. Формат атрибутов [String: Any] больше не поддерживается. Вы должны использовать [NSAttributedString.Key: Any].

Например: NSForegroundColorAttributeName -> NSAttributedString.Key.foregroundColor

Во-вторых, шрифт AvenirNext не имеет стиля "Demi", он имеет только "DemiBold".

let titleAttributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.foregroundColor: UIColor.white, NSAttributedString.Key.font: UIFont(name: "AvenirNext-DemiBold", size: CGFloat(14.0)) as Any]
let selectedTitleAttributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.foregroundColor: UIColor.white, NSAttributedString.Key.font: UIFont(name: "AvenirNext-DemiBold", size: CGFloat(14.0)) as Any]
...