2016-07-18 4 views
0

Я добавил UIView в раскадровку (называемый swipedView), и я не задавал никаких ограничений автомакета. Ничего. Теперь в коде я хочу добавить некоторые ограничения. Чтобы проверить это, я хочу привязать его по сторонам экрана (так что это полноэкранный режим).Создать ограничения с кодом - получить ошибку «Невозможно одновременно удовлетворить ограничениям»

Когда я бегу, я получаю сообщение длинную ошибку, что-то вроде:

2016-07-18 22:59:07.990 FindTheWay[87145:18423835] Unable to simultaneously satisfy constraints. 
    Probably at least one of the constraints in the following list is one you don't want. 
    Try this: 
     (1) look at each constraint and try to figure out which you don't expect; 
     (2) find the code that added the unwanted constraint or constraints and fix it. 
(
    "<NSLayoutConstraint:0x7ff02d11a6e0 V:|-(0)-[UIView:0x7ff02b479a40] (Names: '|':UIView:0x7ff02b450100)>", 
    "<NSIBPrototypingLayoutConstraint:0x7ff02b416a50 'IB auto generated at build time for view with fixed frame' V:|-(20)-[UIView:0x7ff02b479a40] (Names: '|':UIView:0x7ff02b450100)>" 
) 

Will attempt to recover by breaking constraint 
<NSIBPrototypingLayoutConstraint:0x7ff02b416a50 'IB auto generated at build time for view with fixed frame' V:|-(20)-[UIView:0x7ff02b479a40] (Names: '|':UIView:0x7ff02b450100)> 

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger. 
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful. 

Это мой ViewController

import UIKit 

class ViewController: UIViewController { 

    @IBOutlet weak var swipedView: UIView! 
    @IBOutlet weak var foregroundView: UIView! 
    override func viewDidLoad() { 
     super.viewDidLoad() 
     // that was a proposed fix to my problem I found in the internet. Didn't work 
     view.translatesAutoresizingMaskIntoConstraints = false 

    } 

    override func viewDidAppear(animated: Bool) { 

     let pinTop = NSLayoutConstraint(item: swipedView, attribute: .Top, relatedBy: .Equal, toItem: view, attribute: .Top, multiplier: 1.0, constant: 0) 
     let pinLeft = NSLayoutConstraint(item: swipedView, attribute: .Leading, relatedBy: .Equal, toItem: view, attribute: .Leading, multiplier: 1.0, constant: 0) 
     let pinRight = NSLayoutConstraint(item: swipedView, attribute: .Trailing, relatedBy: .Equal, toItem: view, attribute: .Trailing, multiplier: 1.0, constant: 0) 
     let pinBottom = NSLayoutConstraint(item: swipedView, attribute: .Bottom, relatedBy: .Equal, toItem: view, attribute: .Bottom, multiplier: 1.0, constant: 0) 

     NSLayoutConstraint.activateConstraints([pinTop, pinLeft, pinRight, pinBottom]) 

    } 

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

Я совершенно новой для настройки ограничений с помощью кода, так что я» Я не знаю, как с этим бороться. Я проверил несколько похожих вопросов, которые я нашел на stackOverflow, но ничего мне не помогло, к сожалению.

+0

Пробовал, что. Хотя я не нашел такую ​​функцию, только логическое значение для установки на false – Quantm

+1

Вы пробовали вещь о 'NSIBPrototypingLayoutConstraint', на которую ссылались ссылки на ответ? – dan

+0

Я тоже пробовал, да. И теперь это работает (мне пришлось что-то изменить, см. Ответ З.Гски). Я не знаю почему. Я собираюсь опубликовать ответ – Quantm

ответ

2

Set swipedView 's translatesAutoresizingMaskIntoConstraints к false, не view' s.

import UIKit 

class ViewController: UIViewController { 

    @IBOutlet weak var swipedView: UIView! 
    @IBOutlet weak var foregroundView: UIView! 
    override func viewDidLoad() { 
     super.viewDidLoad() 
     // that was a proposed fix to my problem I found in the internet. Didn't work 
     swipedView.translatesAutoresizingMaskIntoConstraints = false 

    } 

    override func viewDidAppear(animated: Bool) { 

     let pinTop = NSLayoutConstraint(item: swipedView, attribute: .Top, relatedBy: .Equal, toItem: view, attribute: .Top, multiplier: 1.0, constant: 0) 
     let pinLeft = NSLayoutConstraint(item: swipedView, attribute: .Leading, relatedBy: .Equal, toItem: view, attribute: .Leading, multiplier: 1.0, constant: 0) 
     let pinRight = NSLayoutConstraint(item: swipedView, attribute: .Trailing, relatedBy: .Equal, toItem: view, attribute: .Trailing, multiplier: 1.0, constant: 0) 
     let pinBottom = NSLayoutConstraint(item: swipedView, attribute: .Bottom, relatedBy: .Equal, toItem: view, attribute: .Bottom, multiplier: 1.0, constant: 0) 

     NSLayoutConstraint.activateConstraints([pinTop, pinLeft, pinRight, pinBottom]) 

    } 

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

Причина этого решения в конечном итоге работа может быть найден в Apple's Documentation.

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

При установке translatesAutoresizingMaskIntoConstraints в true, мы говорим, что мы хотим, чтобы размер соответстующего View и положение, чтобы превратиться в фактические ограничения.

Устанавливая translatesAutoresizingMaskIntoConstraints к false, мы говорим, что размер связанных с View и позиция не должна быть превращена ограничений по каким-либо причинам (в данном случае, мы создаем наши собственные).

Поскольку мы не надеюсь применять ограничения, которые модифицируют и размер и положение view, но на самом деле swipedView, нам нужно установить swipedView «s translatesAutoresizingMaskIntoConstraints равным false.

0

У меня была такая же проблема при использовании конструктора интерфейса, и решение заключалось в том, чтобы определить ограничение, вызывающее предупреждения (возможно, путем комментирования их по одному в этом случае), а затем установив приоритет этого ограничения до 999, а не 1000 (что я считаю дефолтом). Программным, вы делаете это с (. Замена «ограничение» с тем, что пораженная ограничение)

constraint.priority = 999 

Это работает для меня несколько раз, и не влияет на расположение, но очищает предупреждения. Я думаю, что 999 - это эквивалент слова «как можно ближе, но не беспокойтесь об этом», поэтому вы не получите предупреждения, если ограничение не удовлетворится крошечной суммой. Надеюсь, это поможет.

+0

, но проблема в том, что каждое ограничение вызывало эту ошибку (я пробовал комментировать их один за другим). – Quantm

0

Используйте технику, упомянутые в этой статье: http://travisjeffery.com/b/2013/11/preventing-ib-auto-generated-at-build-time-for-view-with-fixed-frame-when-using-auto-layout/

Причина, почему он не работает для меня была ошибка, которую я сделал с

view.translatesAutoresizingMaskIntoConstraints = false

Он должен быть

swipedView.translatesAutoresizingMaskIntoConstraints = false

Теперь это работает. Я не знаю, почему (может быть, некоторые могут объяснить?)

Спасибо @ZGski и @dan

+0

Если ответ, который я дал, закончил тем, что сделал трюк, не могли бы вы пометить его как принятое. – ZGski

+0

Я не уверен, потому что, не добавляя эти ограничения в раскадровку (и удаляя их во время выполнения), ваш ответ не будет работать. Это комбинация обоих. Правила, рассматривающие такие вещи, довольно строгие в stackoverflow, поэтому я не уверен. EDIT: Если бы вы могли добавить это к своему ответу, я был бы рад отметить его как правильный ответ :) – Quantm

+0

О, я понимаю – ZGski

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