Обновление UILabels Вне Экрана, Вызывающее Их "Привязку" Назад
Справочная Информация
Я создаю крошечный секундомер. Он состоит из основного вида с меткой, отображающей время, и двух кнопок: start & stop.
Кнопка start активирует NSTimers
, которая затем вызывает методы, вычисляющие прошедшее время, а затем обновляет метки соответствующим образом. Кнопка стоп просто делает таймеры недействительными.
В верхнем правом углу есть кнопка со стрелкой, которая должна переместить все элементы пользовательского интерфейса влево и показать меню. Эта работа отлично, когда таймеры и не работают, и тем самым метки не обновляются.
Выпуск
Однако при одновременном запуске таймеров и, таким образом, обновлении меток вскоре после начала анимации все возвращается в прежнее положение. При отключении таймеров с помощью кнопки stop анимация снова работает нормально.
Демо
Код
Анимация в toggleMenu()
UIView.animateWithDuration(0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 0.5, options: .CurveEaseOut, animations: {
if self.arrow.frame.origin.x >= screenBounds.width/2 {
//if menu is NOT visible (mainView ON-SCREEN, menu right)
for element in self.UIElements {element.frame.origin.x -= screenBounds.width}
self.arrow.frame.origin.x = 0
self.arrow.transform = CGAffineTransformMakeRotation(CGFloat(-M_PI))
} else {
//if menu IS visible (mainView left, menu ON-SCREEN)
for element in self.UIElements {element.frame.origin.x += screenBounds.width}
self.arrow.frame.origin.x = screenBounds.width-self.arrow.frame.width
self.arrow.transform = CGAffineTransformMakeRotation(CGFloat(0))
}
}, completion: nil)
Обновление меток в таймере называется updateTime()
let currentTime = NSDate.timeIntervalSinceReferenceDate()
var elapsedTime: NSTimeInterval = currentTime - startTime
let hrs = UInt8(elapsedTime/3600)
elapsedTime -= NSTimeInterval(hrs)*3600
let mins = UInt8(elapsedTime/60)
elapsedTime -= NSTimeInterval(mins)*60
let secs = UInt8(elapsedTime)
elapsedTime -= NSTimeInterval(secs)
let strHrs = String(format: "%02d", hrs)
let strMins = String(format: "%02d", mins)
let strSecs = String(format: "%02d", secs)
//update time labels
self.time.text = "(strHrs):(strMins)"
self.secs.text = "(strSecs)"
Попытки
Безуспешно я пытался...
- ...прячется на этикетках как только анимация заканчивается
- ...анимация / скрытие супервизора всех элементов после завершения анимации (
clipsToBounds
Установить true)
Примечание
Я прикинул...
- ...комментируя строки, где метки обновляются "исправляет" проблему
- ...анимация Элементы пользовательского интерфейса для перемещения только пару пикселей (например, 100px) вызывает ту же проблему, а это означает, что проблема происходит на экране и за его пределами
Есть какие-нибудь мысли?
Заранее спасибо!
1 ответ:
При обновлении меток запускается Auto Layout , который возвращает элементы пользовательского интерфейса туда, где они должны быть ограничены. Вы не должны изменять фреймы объектов, находящихся под управлением Auto Layout , иначе вы получите неожиданные результаты.
Вместо обновления
origin.x
элементов пользовательского интерфейса создайте@IBOutlet
s дляNSLayoutContraints
, расположив их горизонтально, а затем обновите свойствоconstant
ограничений и вызовитеself.view.layoutIfNeeded()
в анимации петля.Может быть проще сделать все элементы пользовательского интерфейса подвидом UIView верхнего уровня, и тогда вам нужно будет обновить только одно ограничение, которое помещает этот UIView горизонтально, чтобы переместить его за пределы экрана.