2017-02-06 7 views
0

У меня есть черный разделительView в середине экрана, разделяющий topContainerView (оранжевый) и bottomContainerView (зеленый). РазделительView можно перетаскивать вверх и вниз с помощью panGesture, но я не могу получить верхнее и нижнее представления, чтобы обновлять их ограничения и изменять размер. В нижней части оранжевого вида и верхней части зеленого вида всегда следует придерживаться разделителя.Ограничения обновления с помощью UIPanGestureRecognizer

Вот код, который я (ОБНОВЛЕНО включать объявления переменных):

let separatorView: UIView = { 
 
    let view = UIView() 
 
    view.backgroundColor = UIColor.black 
 
    view.translatesAutoresizingMaskIntoConstraints = false 
 
    return view 
 
}() 
 

 
let topContainerView : UIView = { 
 
    let view = UIView() 
 
    view.backgroundColor = UIColor.orange 
 
    view.translatesAutoresizingMaskIntoConstraints = false 
 
    return view 
 
}() 
 

 
let bottomContainerView : UIView = { 
 
    let view = UIView() 
 
    view.backgroundColor = UIColor.green 
 
    view.translatesAutoresizingMaskIntoConstraints = false 
 
    return view 
 
}() 
 

 
override func viewDidLoad() { 
 
     super.viewDidLoad() 
 
     self.addViews() 
 
     let panGesture = UIPanGestureRecognizer(target: self, action: #selector(detectPan(recognizer:))) 
 
     panGesture.delaysTouchesBegan = false 
 
     panGesture.delaysTouchesEnded = false 
 
     separatorView.addGestureRecognizer(panGesture) 
 
    } 
 

 
    override func didReceiveMemoryWarning() { 
 
     super.didReceiveMemoryWarning() 
 
     // Dispose of any resources that can be recreated. 
 
    } 
 
    
 
    func addViews() { 
 
     
 
     view.addSubview(topContainerView) 
 
     view.addSubview(bottomContainerView) 
 
     view.addSubview(separatorView) 
 
     
 
     separatorView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true 
 
     separatorView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true 
 
     separatorView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true 
 
     separatorView.heightAnchor.constraint(equalToConstant: 50).isActive = true 
 
     
 
     topContainerView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true 
 
     topContainerView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true 
 
     topContainerView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true 
 
     topContainerView.bottomAnchor.constraint(equalTo: separatorView.topAnchor).isActive = true 
 
     
 
     bottomContainerView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true 
 
     bottomContainerView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true 
 
     bottomContainerView.topAnchor.constraint(equalTo: separatorView.bottomAnchor).isActive = true 
 
     bottomContainerView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true 
 
    } 
 
    
 
    func detectPan(recognizer: UIPanGestureRecognizer) { 
 
     let translation = recognizer.translation(in: self.view) 
 
     separatorView.center = CGPoint(x: view.center.x, y: lastLocation.y + translation.y) 
 
    } 
 
    
 
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 
 
     self.view.bringSubview(toFront: separatorView) 
 
     lastLocation = separatorView.center 
 
    }

enter image description here

enter image description here

+0

Вы установили свои представления '' translatesAutoresizingMaskIntoConstraints' в 'false'? – Honey

+0

Я сделал, для каждого вида – kerbelda

+0

где вы это сделали? Я не вижу его в вашем коде – Honey

ответ

3

При использовании Autolayout вы не можете просто изменить кадр элементов (это то, что вы делаете неявно путем изменения свойства center). Ну, вы можете, но это не повлияет на какие-либо другие элементы (как вы нашли), и как только будет запущен автозапуск, ваши изменения в кадре будут сброшены.

Вам необходимо управлять ограничениями, чтобы Autolayout выдавал желаемый результат.

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

let separatorView: UIView = { 
    let view = UIView() 
    view.backgroundColor = UIColor.black 
    view.translatesAutoresizingMaskIntoConstraints = false 
    return view 
}() 

let topContainerView : UIView = { 
    let view = UIView() 
    view.backgroundColor = UIColor.orange 
    view.translatesAutoresizingMaskIntoConstraints = false 
    return view 
}() 

let bottomContainerView : UIView = { 
    let view = UIView() 
    view.backgroundColor = UIColor.green 
    view.translatesAutoresizingMaskIntoConstraints = false 
    return view 
}() 

var centerConstraint: NSLayoutConstraint! 

var startingConstant: CGFloat = 0.0 

override func viewDidLoad() { 
    super.viewDidLoad() 
    self.addViews() 
    let panGesture = UIPanGestureRecognizer(target: self, action: #selector(detectPan(recognizer:))) 
    panGesture.delaysTouchesBegan = false 
    panGesture.delaysTouchesEnded = false 
    separatorView.addGestureRecognizer(panGesture) 
} 

override func didReceiveMemoryWarning() { 
    super.didReceiveMemoryWarning() 
    // Dispose of any resources that can be recreated. 
} 

func addViews() { 

    view.addSubview(topContainerView) 
    view.addSubview(bottomContainerView) 
    view.addSubview(separatorView) 

    separatorView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true 
    separatorView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true 

    self.centerConstraint = separatorView.centerYAnchor.constraint(equalTo: view.centerYAnchor) 
    self.centerConstraint.isActive = true 

    separatorView.heightAnchor.constraint(equalToConstant: 50).isActive = true 

    topContainerView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true 
    topContainerView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true 
    topContainerView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true 
    topContainerView.bottomAnchor.constraint(equalTo: separatorView.topAnchor).isActive = true 

    bottomContainerView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true 
    bottomContainerView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true 
    bottomContainerView.topAnchor.constraint(equalTo: separatorView.bottomAnchor).isActive = true 
    bottomContainerView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true 
} 

func detectPan(recognizer: UIPanGestureRecognizer) { 

    switch recognizer.state { 
    case .began: 
     self.startingConstant = self.centerConstraint.constant 
    case .changed: 
     let translation = recognizer.translation(in: self.view) 
     self.centerConstraint.constant = self.startingConstant + translation.y 
    default: 
     break 
    } 
} 
+0

Yup, это то, что я закончил делать. Изменение центра ничего не обновляло. Придется изменить константу константы центра. Благодаря! – kerbelda

Смежные вопросы