2015-11-28 3 views
6

Я сохраняю скриншот в «Инструменты автоматизации», но некоторые элементы управления отсутствуют на этом снимке экрана. Похоже, что программно добавленные элементы управления «игнорируются».Инструменты Автоматический скриншот игнорирует программно добавленные элементы управления

Как это исправить?

Руководство скриншот в симуляторе: (обратите внимание на желтый прямоугольник)

Screenshot in Simulator with Yellow Button

Скриншот в инструменты автоматизации:

Screenshot in Instruments Automation without Yellow Button

Сценарий автоматизации:

var target = UIATarget.localTarget(); 
target.delay(0.5) 
target.captureScreenWithName("screenshot1.png"); 

Я создал новое приложение с одним представлением в Xcode (универсальный, объективный-c). Я добавил кнопку и ярлык с некоторыми ограничениями для автоматического макета в раскадровке.

Я добавил этот код, чтобы добавить желтую кнопку программно:

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    // Do any additional setup after loading the view, typically from a nib. 

    UIButton *b = [[UIButton alloc] init]; 
    b.backgroundColor = [UIColor yellowColor]; 
    [b setTitle:@"Extra" forState:UIControlStateNormal]; 
    [b setTranslatesAutoresizingMaskIntoConstraints:NO]; 
    [self.view addSubview:b]; 
    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:b attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTopMargin multiplier:1.0 constant:0.0]]; 
    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:b attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTrailingMargin multiplier:1.0 constant:0.0]]; 

    [self.view setNeedsUpdateConstraints]; 
    // Correction: - initially I used the line below, but that was wrong 
    // The problem is not solved with using setNeedsUpdateConstraints. 
    // [self.view updateConstraints]; 
} 

Я использую Xcode версии 7.1.1 (7B1005), моя ОС El Capitan 10.11.1 (15B42). Я знаю, что он работал в более ранних версиях, потому что я использую ui-screen-shooter для скриншотов моего приложения, и проблемы возникают сейчас, и он работал раньше. Это не проблема с ui-screen-shooter, потому что я могу воспроизвести его только с помощью автоматизации инструментов.

Что я могу сделать?

EDIT:

Одно из различий между элементами управления в раскадровки и созданные вручную из них может быть идентификатор объекта, который можно увидеть в источнике раскадровки. В случае, если это будет проблемой, могу ли я установить id для созданных вручную элементов управления? (Или это теряется, когда сцена читается из раскадровки?)

EDIT 2:

Я принес все свойства элементов в поле зрения контроллера представления (через ObjC/время выполнения) и по сравнению значений свойств двух кнопок. Есть небольшие различия: (не будет включать в себя идентичные записи)

 
Button from Storyboard   | Manual Button 
----------------------------------------------------------------- 
"_defaultRenderingMode" = 2;  | "_defaultRenderingMode" = 1; 
text = Button;     | text = Extra; 
           | 
     (several position values slightly different) 
           | 
description contains:   | 
"autoresize = RM+BM;"   | 
           | backgroundColorSystemColorName = yellowColor; 

EDIT 3:

Скриншот выхода target.logElementTree():

target.logElementTree() output

EDIT 4:

Я добавил

[UIButton appearance].backgroundColor = [UIColor yellowColor]; 

и все кнопки теперь имеют желтый фон, однако кнопка «Экстра» не находится на скриншоте.

Я не ориентирован в основном на внешний вид.Я также пробовал

UIButton *b = [UIButton buttonWithType:UIButtonTypeSystem]; 

так что кнопка похожа на типичные синие кнопки. Тем не менее кнопка не появляется на снимке экрана автоматизации.

EDIT 5:

В случае уместно: я могу доступ к элементам управления из сценария автоматизации и сделать отводы - например (из другого приложения, а не этот тест код):

target.frontMostApp().mainWindow().buttons()[25].tap() 

Отламы обрабатываются, поэтому скрипт автоматизации может обращаться к элементам управления.

EDIT 6: Я создал отчет об ошибке в системе bugreport от Apple. Если вы можете воспроизвести его, может быть хорошо сделать то же самое (по крайней мере, так я понял предполагаемое использование отчета об ошибках в Apple).

EDIT 7: (спасибо quellish за ваш ответ - обрабатывая мою первую волну мыслей здесь :) Я исправил ошибку в коде - я позвонил [self.view updateConstraints];, но это должно быть [self.view setNeedsUpdateConstraints];. Однако это не повлияло на результаты скриншотов автоматизации.

Мне было интересно, были ли ограничения обновлены и зарегистрированы в updateViewConstraints и некоторые другие. Это, как он вошел в то время как приложение загружается:

viewDidLoad 
viewWillAppear 
updateViewConstraints 
viewWillLayoutSubviews 
viewWillLayoutSubviews 
viewDidAppear 

Так что, когда я добавить кнопку и ограничения в viewDidLoad и updateViewConstraints называется, я бы предположить, что все ограничения разрешаются, когда viewDidAppear называется.

Я сделал быстрый тест, используя это в viewDidAppear: (пока не уверен, является ли путь - У меня есть небольшой опыт работы с доступностью.)

_extraButton.accessibilityFrame = UIAccessibilityConvertFrameToScreenCoordinates(_extraButton.frame, self.view); 

скриншот автоматизации остается белым.

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

+0

Обновите свой вопрос с помощью результата 'logElementTree()'. – quellish

+0

@quellish Сделал это - когда я выбираю линию с помощью кнопки «Экстра», маленький снимок этой кнопки отображается справа. Область совпадает, но кнопки там нет.На снимке симулятора кнопка имеет белый цвет текста. Однако в приложениях, которые я в конечном итоге хочу «экранировать», элементы имеют черный цвет текста, но текст не отображается на скриншоте инструментов. –

+0

Это почти наверняка проблема времени. Вы видите другое поведение, если вы используете стиль UIAppearance для стилизации кнопки? – quellish

ответ

0

Проблема, которую вы видите, связана с несколькими факторами. Как указано в вашем вопросе, ваша проблема заключается в следующем:

  • Скриншоты UIAutomation не будут содержать вашу стилизованную кнопку при условии, что вы включили тестовый проект и сценарий автоматизации.

При различных условиях вы видите другое поведение:

  • Когда кнопка конкретизируется через перо или раскадровку проблема не возникает, только когда кнопка объявлена ​​и добавляется к иерархии представлений в коде (в частности, viewDidLoad контроллера вида).

  • Эта кнопка отображается в скриншотах UIAutomation при запуске в более ранних версиях iOS (то есть iOS 8).

Тем не менее, если убрать ограничения добавлены в viewDidLoad вы увидите стиль кнопки начинают появляться на скриншотах. Это должен быть намек - ограничения являются частью проблемы.

При ограничении на решение механизма компоновки он пытается сделать как можно больше работы партиями, сдерживая ограничения производительности. Когда кнопка и ограничения описаны в nib или раскадровке, механизм ограничений будет получать их все сразу и намного раньше в жизненном цикле иерархии представления. Из-за этого шаги процесса компоновки могут быть значительно упрощены.

Однако, если ограничение ограничивается в жизненном цикле иерархии представлений, необходимо переопределить ограничения. Подумайте о добавленных ограничениях, которые добавляются в очередь, и механизм компоновки будет переоценивать их в следующий раз, когда очередь будет «полной». UIAutomation подключается к API-интерфейсам UIAccessibility, чтобы сделать это - и доступность может не знать и не заботиться о том, что происходит с макетом визуального представления. Визуальное представление может измениться, но не таким образом, которое влияет на доступность, и, таким образом, представление UIAutomation о мире.

iOS 9 изменил несколько вещей о том, как работает макет под капотом, поэтому вы видите эту проблему сейчас.

Есть целый ряд курсов действий вы можете взять с собой:

  • Построить иерархию вида в пере или раскадровке. Это даст вам самый последовательный опыт и имеет производительность и другие преимущества.

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

  • Вместо произвольной задержки в сценарии автоматизации используйте таймауты UIAutomation эффективно, чтобы дождаться появления элемента. Это covered in the documentation и является лучшей практикой. Сделайте его недоступным или недействительным до завершения макета.

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

+0

Спасибо за ответ - я должен подумать о деталях - некоторые мне еще не имеют смысла. Действия 1) Построение пользовательского интерфейса в раскадровке/кеге не возможно (переменный набор элементов управления и т. Д.) Действия 2) Имейте об этом подумать. Действия 3) Я обязательно посмотрю на них. –

+0

Я наградил награду сейчас, потому что она истекла. –

0

Проблема с автоматизацией инструментов, вероятно, не будет исправлена.

Решение часть 1: «Тесты интерфейса Xcode 7» - это новая «Автоматизация инструментов».

Решение часть 2: fastlane/snapshot - это новый ui-screen-shooter. (ui-screen-shooter устарел от своего автора, и он рекомендует переключиться на fastlane/snapshot.)

Итак, я перейду к fastlane/snapshot, и моя проблема, надеюсь, будет решена.