#objective-c #macos #macos-sierra
#objective-c #macos #macos-sierra
Вопрос:
Я просто пытаюсь изменить положение своих кнопок, немного отрегулировав его, чтобы он был правильно размещен в моем приложении. До сих пор в предыдущих версиях (минимум 10.8) он работал, но прямо в последней версии Mac (10.12 sierra) он каким-то образом не меняет свой фрейм или положение..
пример:
-(void)awakeFromNib
{
[self.mybutton setFrameOrigin:NSMakePoint(0,0)]; // not working...
[self.mybutton setFrame:NSRectFromCGRect(CGRectMake(0,0,100,100)]; // also not working...
}
Я что-то упускаю? Это должно быть как прямая настройка frame.
Комментарии:
1. Извините, ложная тревога это было потому, что я использовал более старый Xcode (версия 7.3) для создания приложения, в результате чего setFrameOrigin не работал, поэтому я упаковываю новое приложение с последней версией Xcode.
Ответ №1:
Я столкнулся с той же проблемой.
У меня есть NSImageView
в моем NSWindow
, и мне нужно переместить его после того, как пользователь нажмет на него (это своего рода окно калибровки). Создается NSImageView
с помощью Xcode 6.2 IB.
Однако по другим причинам мне нужно скомпилировать мое приложение с этой более старой версией Xcode (6.2, на Mavericks), поэтому я не могу обновиться до Xcode 8, как это было предложено OP в комментариях к вопросу. Я даже не пробовал решение OP.
TL; DR: Для меня это была проблема с автозаполнением. Похоже, что macOS 10.12 Sierra имеет более строгие правила автозапуска, чем в macOS 10.9-10.10-10.11 (где мое приложение тестируется и поддерживается). Перейдите сразу к варианту 3 для лучшего решения.
Вариант 1 (сбой в macOS 10.9):
Первый обходной путь — просто удалить NSView
из своего супервизора, отправить setFrameOrigin
, а затем повторно добавить его в супервизор:
NSView *supView = myView.superview;
[myView setFrameOrigin:NSZeroPoint];
[supView addSubview:myView];
Это довольно хорошо работает в macOS 10.12 Sierra, однако при тестировании на Mavericks myView
всегда застревает в позиции (0,0).
Затем я понимаю, что на самом NSWindow
деле включена функция автозапуска и установлены некоторые ограничения для некоторых других NSView
(но НЕ для myView
): я использую смешанный подход с ручной компоновкой и автоматической компоновкой.
Оказывается, это основная причина setFrameOrigin
того, что в моем случае это не работает.
Вариант 2 (быстрый способ):
Есть волшебная ручка, которая поможет вам при переходе от традиционного подхода, не связанного с автоматическим описанием, к подходу с автоматическим описанием:
myView.translatesAutoresizingMaskIntoConstraints = YES;
Я установил это в своей awakeFromNib
перегрузке: теперь все работает правильно в macOS Sierra.
К сожалению, тестирование на Mavericks показывает некоторые проблемы (снова): хотя поведение правильное ( setFrameOrigin
myView
перемещается), Xcode выдает много предупреждений о автозаполнении на консоли. Однако это кажется одним шагом в правильном направлении и может быть окончательным решением для кого-то другого.
Вариант 3 (решение):
Определите некоторые NSLayoutConstraint
s myView
с помощью IB, затем используйте removeConstraints
и addConstraints
в супервизоре:
NSView *supView = myView.superview;
[supView removeConstraints:@[self.bottomConstraint, self.rightConstraint]];
[supView addConstraints:@[self.topConstraint, self.leftConstraint]];
[supView layoutSubtreeIfNeeded];
ПРИМЕЧАНИЕ: layoutSubtreeIfNeeded
необязательно; вы должны использовать его, если вам нужно работать с myView.frame
использованием обновленных значений (как в моем случае).
Этот код корректно работает на macOS 10.9-10.10-10.11-10.12 .