2015-04-17 2 views
1

У меня 3 просмотров в IB. View One (1) имеет представление и UIImage, которые я использую в качестве фона для этого ViewController. Просмотреть два (2) (подробный вид) и просмотреть три (3) (вид параметров) - это контейнеры, которые расположены друг на друге. У меня есть кнопка в View 2, что анимация View 2 находится слева и перемещает Вид 3 справа. И я могу вернуться из View 3, двигаясь вправо, и возвращая View 2 слева.Просмотр анимации контейнера не работает должным образом при смене фонового изображения

Вот что мой Outline документ выглядит следующим образом: enter image description here

Белый BG, это просто фон под названием бара, на всякий случай, если кто-то интересно.

Вот код, который я использую, чтобы сделать эти анимации:

func showOptions(){ 
    println("show options") 

    optionsView.center.x = self.view.bounds.width + self.view.bounds.width/2 
    optionsView.hidden = false 

    UIView.animateWithDuration(0.5, animations: { 

     self.blurView.alpha = 1 

     // slide containers around 
     // println(self.view.bounds.width) 

     self.detailsView.center.x = -self.view.bounds.width * 2 
     self.optionsView.center.x = self.view.bounds.width/2 
    }) 
} 
func showDetails(){ 
    println("show detials") 

    optionsView.center.x = self.view.bounds.width/2 

    UIView.animateWithDuration(0.5, animations: { 

     self.blurView.alpha = 0 

     // slide containers around 
     // println(self.view.bounds.width) 

     self.detailsView.center.x = self.view.bounds.width/2 
     println("\(self.optionsView.center.x) this is center X value 1") 

     self.optionsView.center.x = self.view.bounds.width * 2 
     println("\(self.optionsView.center.x) this is center X value 2") 

    }, completion: { 
      (value: Bool) in 
      println("\(self.optionsView.center.x) this is center X value 3") 
    }) 
} 

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

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

  • 160,0 это центр X значение 1
  • 640,0 это ЕКС тер X значение 2
  • 640,0 это Центр значения Х 3

Когда я изменяю из фото я получаю эти значения:

  • 160,0 это центр X значение 1
  • 640,0 это центр X значение 2
  • 160,0 это центр X значение 3

Что не работает, когда я попробуйте изменить образ фонового представления для этого контроллера вида.

let par3 = UIImage(named: "par3.png") 
backgroundImage.image = par3 
    // println("par three") 
    showDetails() 

Когда я меняю фоновое фото, оба вида 2 и 3 видят на экране слева. Я просто не знаю, почему. Связано ли это с изменением ширины изменяемого вида контроллера при отключении фоновой фотографии?

Спасибо за помощь!

ответ

4

Похоже, вы только наполовину обнимаете Автомат. Вы используете его, чтобы сначала изложить свои взгляды, но тогда вы не используете его, когда будете анимировать представления. Вы изменяете положение центра x, это старый способ анимации. Это похоже на работу, но потом я думаю, что при исходном обращении все возвращается к исходным ограничениям, так как это вызывает вызов layoutIfNeeded() под капотом, который использует ограничения, чтобы поместить все обратно, как это было первоначально.

Вместо того, чтобы изменять положение точек в центре x, вам нужно изменить свой подход, чтобы вместо этого изменить ограничения. Это будет означать, что даже при замене изображения ваши ограничения будут по-прежнему точными, и все должно работать должным образом. Это требует настройки ваших ограничений определенным образом, которые я попытаюсь продемонстрировать.

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

Моя раскадровка выглядит следующим образом:

storyboard setup

Вот что инспектор выглядит следующим образом:

storyboard inspector

Несколько пунктов о настройке раскадровки:

  • I иметь основной вид контейнера tha t является подпунктом родительского представления. В этом основном представлении контейнера ClipSubviews установлен на YES, так что, когда мы перемещаем представления влево и вправо, они не отображаются за пределами основного контейнера.
  • Оба варианта и вид контейнера детали имеют ограничения, установленные в соответствии с шириной и высотой основного вида контейнера.
  • Левая сторона вид контейнера детали настроена на правую сторону правой стороны от вида контейнера параметров, то есть [опции] [подробно]. Они не находятся непосредственно друг над другом.
  • Детальный вид контейнера имеет ограничение, так что верхние края имеют верхний край представления контейнера параметров.
  • Вид контейнера параметров настроен с ограничениями для выравнивания вверху слева вверху основного вида контейнера. Это в сочетании с предыдущими двумя пулями означает, что изначально вид контейнера детали находится на экране справа. У меня есть ссылка в контроллере родительского представления на ограничение, которое выравнивает левую часть представления контейнера параметров с левой стороны mainContainerView (тот, который выбран в приведенном выше скриншоте), и это то, что я использую для анимации всего ,

Это то, что родительский класс выглядит следующим образом:

class ParentViewController: UIViewController, OptionsViewControllerDelegate, DetailViewControllerDelegate { 

    struct Constants { 
     static let optionsEmbedSegue = "optionsEmbedSegue" 
     static let detailEmbedSegue = "detailEmbedSegue" 
    } 

    @IBOutlet weak var mainContainerView: UIView! 

    @IBOutlet weak var optionsLeadingSpaceConstraint: NSLayoutConstraint! 

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { 
     if segue.identifier == Constants.optionsEmbedSegue { 
      let childViewController = segue.destinationViewController as OptionsViewController 
      childViewController.delegate = self 
     } else if segue.identifier == Constants.detailEmbedSegue { 
      let childViewController = segue.destinationViewController as DetailViewController 
      childViewController.delegate = self 
     } 
    } 

    func optionsViewControllerDidSelectToShowDetail(optionsViewController: OptionsViewController) { 
     animateOptionsToNewXPosition(-CGRectGetWidth(mainContainerView.bounds)) 
    } 

    func detailViewControllerDidSelectToGoBack(detailViewController: DetailViewController) { 
     animateOptionsToNewXPosition(0) 
    } 

    func animateOptionsToNewXPosition(xPosition: CGFloat) { 
     optionsLeadingSpaceConstraint.constant = xPosition 

     UIView.animateWithDuration(0.5, animations: {() -> Void in 
      self.mainContainerView.layoutIfNeeded() 
     }) 
    } 
} 

Если вы посмотрите на метод optionsViewControllerDidSelectToShowDetail, вы увидите строку animateOptionsToNewXPosition(-CGRectGetWidth(mainContainerView.bounds)). Это перемещает контроллер представления параметров влево в размере ширины основного вида контейнера. Это означает, что он исчезнет слева от экрана, и из-за всех других ограничений он перетащит контроллер подробного представления с ним, показывая контроллер подробного представления в mainContainerView. Противоположное происходит в методе detailViewControllerDidSelectToGoBack, просто устанавливая константу в этом ограничении обратно на 0, что возвращает контроллер представления параметров и толкает detailViewController вправо.

Я надеюсь, что это поможет.