Обновление High Sierra вызывает переворот и шифрование NSTableView

Я обновляю существующий проект, который работал годами в High Sierra. Представление загружается правильно и выглядит как всегда:

Нормальный (правильный) внешний вид

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

Зашифрованный (неправильный) внешний вид

Обратите внимание, что заголовок Info опускается вниз, текстовые элементы в левой части отображаются в обратном порядке, а дата и выпадающий текст переворачиваются. Когда это происходит, взаимодействие с мышью кажется слишком сложным.

Я не уверен, с чего начать с решения этого, у кого-нибудь есть идеи?

Это использует xcode 9 beta 5 и High Sierra Beta 6.
Обновление: это также в xcode 9 GM и High Sierra GM Seed

Обновить

Я определил, что это происходит, когда я вызываю reloadData для NSTableView, внутри которого находится это представление. Таким образом, теперь возникает вопрос, как обновить данные таблиц, чтобы они не были слишком сложными.

5 ответов

Решение

Кажется, что reloadData, а также reloadDataForRowIndexes:columnIndexes: оба производят странное поведение в High Sierra. Мой способ обойти это следующим образом:

-(void)refreshAllCells {
    NSMutableIndexSet* rowIndexes = [[NSMutableIndexSet alloc] init];
    if (self.myTable.numberOfRows != 0)
        [rowIndexes addIndexesInRange:NSMakeRange(0, (self.myTable.numberOfRows))];
    [self.myTable removeRowsAtIndexes:rowIndexes withAnimation:NO];
    [self.myTable insertRowsAtIndexes:rowIndexes withAnimation:NO];
}

Если есть лучший ответ, я все равно хотел бы увидеть его.

В IB установите флажок, чтобы использовать CALayers в представлениях вашего tableView. Я включил их для всех представлений в иерархии представлений tableView, и все перелистывания прекратились!

Невозможно опубликовать изображение, так как у меня недостаточно репутации, но по этой ссылке отображается флажок IB:

Параметры Интерфейсного Разработчика

Для меня добавление wantUpdateLayer в мой подкласс решило проблему.

override open var wantsUpdateLayer: Bool { return true }

Я тоже столкнулся с этой ошибкой, и при реализации другого ответа я нашел настоящую причину ошибки из-за исключения, которое теперь возникло:

В моем случае, reloadDataбыл вызван снова, покаreloadDataвсе еще выполнялся. Это вызвало проблемы с рендерингом.

"Петля" возникла как побочный эффект вызова tableView.makeView(withIdentifier: identifier, owner: self) в tableView(_:, viewFor:, row:). Вowner: self вызвал awakeFromNib() повторного вызова контроллера, который, в свою очередь, вызвал reloadData(). В моей настройке я (пока) не использовал отдельные XIB для ячеек таблицы, но использовал ячейки, которые были настроены внутри табличного представления как видимый Interface Builder.

Итак, решение было изменить tableView.makeView(withIdentifier: identifier, owner: self) к tableView.makeView(withIdentifier: identifier, owner: nil) а также использовать отдельные XIB для ячеек таблицы.

Я тоже это испытал. Дальнейшее тестирование показало, что содержимое рисуется, пока обновляется источник данных таблицы просмотра. Устраняя ложные обновления, я смог устранить проблему.

Я перезагружаю данные в методе рисования, однако я переместил код обновления данных за пределы этого метода. Не уверен, поможет ли это ОП, но у меня это сработало.

Была такая же проблема, воспроизводимая на High Sierra и Mojave. Проблема заключалась в NSOutlineView autosaveName, другие решения не помогли. Однако мне нужна была эта функция.

Перемещение добавления / перезагрузки данных в "viewDidAppear()" вместо "viewDidLoad()" решило проблему.

Отредактировано: Это происходит только когда:

  1. автосохранение присутствует
  2. элементы загружаются в viewDidLoad до применения сортировки
  3. тот же список элементов повторно загружается после применения сортировки
  4. все вышеперечисленное происходит на viewDidLoad

Если вы попытаетесь получить доступ к tableView.sortingDescriptors (или NSOutlineView) - он автоматически применит сортировку. Если это происходит до загрузки данных - все нормально.

Загрузка данных в viewDidAppear по-прежнему выглядит лучшим вариантом.

Внезапно я получил несколько писем от клиентов, которые жаловались на то, что все тексты таблиц отображаются вертикально. Все они используют macOS Mojave.

После многих взломов и попыток решения описанных выше решений (но безуспешно) я решил отключить свойство autoSave для NSTableView:

//Swift.print("Now setting autosaveName of primaryView to \(self.className).primary")
//primaryTableView.autosaveName = "\(self.className).primary"
//primaryTableView.autosaveTableColumns = true

Тогда проблема мгновенно исчезла. Но теперь мои клиенты больше не могли изменять и сохранять ширину столбцов и порядок. Таким образом, вместо того, чтобы делать это программно с tableView.autosaveName = "autosavename"; Теперь я установил свойство autoSave в свойствах табличного представления, а также проверил "Информация столбца" в Инспекторе атрибутов (при отображении файла xib). И тогда это работает просто отлично..

Я использую последнюю версию Xcode (10.1 10B61), и проблемы возникли только при использовании macOS Mojava 10.14.0 - 10.14.2 . Высшая Сьерра и Сьерра не доставляли хлопот. Скомпилировал ли я проект в High Sierra или Mojave, не имеет значения.

Поэтому я надеюсь, что это поможет другим людям, столкнувшимся с этой странной проблемой. Я думаю, что это ошибка в MacOS Mojave.

Я вижу это также в 10.13, когда 10.12 работало просто отлично. Мне удалось обойти эту проблему, как ни странно, повторно добавив подпредставления представления ячейки в его [layout]:

- (void)layout{
    if([self needsLayout]){
        for(NSView* v in [[self subviews] copy]){
            [self addSubview:v];
        }
    }

    [super layout];
}
Другие вопросы по тегам