質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

1回答

2089閲覧

autoLayoutのアニメーション後の制約が重複している件につきまして

退会済みユーザー

退会済みユーザー

総合スコア0

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2019/02/25 02:53

前提・実現したいこと

初めて投稿いたします、いざ氏と申します。
当方autoLayoutがよく理解できておらず、皆様のお力をお借りしたいと思い投稿いたしました。
現在テスト的に以下の動作をするアプリを作っています。
<テスト環境>
iOS12.1.4
xcode 10.1
swift 4.2
<動作内容>
1:2つのビューがある(添付コードでは緑、赤)
2:タップすると画面一杯のサイズに拡大される
3:閉じるを押すと、元のサイズに戻る
4:ビュー拡大時にスワイプすると、拡大ビューは横移動(この時もう一方を移動前に拡大)、
下からもう一方が出てくるようにしています。

発生している問題・エラーメッセージ

4の閉じるを押しても画面が縮小されず、以下のエラーが表示されます。
拡大中の制約が重複していることが原因でエラーが表示されていると思われます。

エラーメッセージ
2019-02-25 11:44:16.082031+0900 PLTestAutoLayout_190222[1100:121133] [LayoutConstraints] 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:0x28370e490 V:|-(0)-[PLTestAutoLayout_190222.CustomView:0x10181d3d0] (active, names: '|':UIView:0x101821d00 )>",
"<NSLayoutConstraint:0x283736800 V:|-(200)-[PLTestAutoLayout_190222.CustomView:0x10181d3d0] (active, names: '|':UIView:0x101821d00 )>"
)

該当のソースコード

質問の文字数が10000文字までであったため、CustomViewクラスの実装は省略致します。
import UIKit

class ViewController: UIViewController, CustomViewDelegate {

// 赤ビュー lazy var red: CustomView = CustomView.init(frame: CGRect.zero) // 緑ビュー var green: CustomView = CustomView.init(frame: CGRect.zero) // 保持用 var saveCon : [NSLayoutConstraint] = [] var conGreen : [NSLayoutConstraint] = [] // 緑ビュー制約 var conRed : [NSLayoutConstraint] = [] // 赤ビュー制約 // 拡大 func scaleUp(upView: CustomView) { // 最前面に移動 self.view.bringSubviewToFront(upView) // 赤ビューの制約無効 if upView == red{ NSLayoutConstraint.deactivate(conRed) } // 緑ビューの制約無効 else{ NSLayoutConstraint.deactivate(conGreen) } // 新規制約生成(画面いっぱいに広げる)、有効にする let constA = upView.topAnchor.constraint(equalTo: view.topAnchor) let constB = upView.bottomAnchor.constraint(equalTo: view.bottomAnchor) let constC = upView.leadingAnchor.constraint(equalTo: view.leadingAnchor) let constD = upView.trailingAnchor.constraint(equalTo: view.trailingAnchor) // 作成した制約保持(縮小時に使用するため) saveCon = [constA, constB, constC, constD] NSLayoutConstraint.activate(saveCon) UIView.animate(withDuration: 0.3, animations: { self.view.layoutIfNeeded() }, completion: { finished in }) } // 縮小 func scaleDown(downView: CustomView) { // 保持していた制約を使用して無効にする NSLayoutConstraint.deactivate(saveCon) // 赤ビューの元々の制約有効 if downView == red{ NSLayoutConstraint.activate(conRed) } // 緑ビューの元々の制約有効 else{ NSLayoutConstraint.activate(conGreen) } UIView.animate(withDuration: 0.3, animations: { self.view.layoutIfNeeded() }, completion: { finished in }) } func swipeDirection(sender: UISwipeGestureRecognizer){ let notSwipeView = sender.view != red ? red : green // スワイプされていないビュー:1つ後ろにinsertする //self.view.insertSubview(notSwipeView, at: 0) // スワイプされていないビュー:現在の制約無効 if notSwipeView == red{ NSLayoutConstraint.deactivate(conRed) } else{ NSLayoutConstraint.deactivate(conGreen) } // スワイプされていないビュー:制約有効(拡大) let conNotSwipe1 = notSwipeView.topAnchor.constraint(equalTo: view.topAnchor) let conNotSwipe2 = notSwipeView.bottomAnchor.constraint(equalTo: view.bottomAnchor) let conNotSwipe3 = notSwipeView.leadingAnchor.constraint(equalTo: view.leadingAnchor) let conNotSwipe4 = notSwipeView.trailingAnchor.constraint(equalTo: view.trailingAnchor) NSLayoutConstraint.activate([conNotSwipe1, conNotSwipe2, conNotSwipe3, conNotSwipe4]) DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) { // スワイプビュー:制約無効(拡大) NSLayoutConstraint.deactivate(self.saveCon) // スワイプされていないビュー:制約保持(このビューを縮小するときに使用する) self.saveCon = [conNotSwipe1, conNotSwipe2, conNotSwipe3, conNotSwipe4] // 移動処理 var currentConst : [NSLayoutConstraint]? // 左にスワイプ if sender.direction == UISwipeGestureRecognizer.Direction.left{ let conMove1 = sender.view!.topAnchor.constraint(equalTo: self.view.topAnchor) let conMove2 = sender.view!.bottomAnchor.constraint(equalTo: self.view.bottomAnchor) let conMove3 = sender.view!.widthAnchor.constraint(equalToConstant: 768) let conMove4 = sender.view!.trailingAnchor.constraint(equalTo: self.view.leadingAnchor) currentConst = [conMove1, conMove2, conMove3, conMove4] } // 右にスワイプ else if sender.direction == UISwipeGestureRecognizer.Direction.right{ let conMove1 = sender.view!.topAnchor.constraint(equalTo: self.view.topAnchor) let conMove2 = sender.view!.bottomAnchor.constraint(equalTo: self.view.bottomAnchor) let conMove3 = sender.view!.widthAnchor.constraint(equalToConstant: 768) let conMove4 = sender.view!.leadingAnchor.constraint(equalTo: self.view.trailingAnchor) currentConst = [conMove1, conMove2, conMove3, conMove4] } // スワイプビュー:制約有効(移動) NSLayoutConstraint.activate(currentConst!) UIView.animate(withDuration: 0.3, animations: { self.view.layoutIfNeeded() }, completion: { finished in // スワイプビュー:制約無効 NSLayoutConstraint.deactivate(currentConst!) // スワイプビュー:元々の制約有効(縮小) if sender.view! == self.red{ NSLayoutConstraint.activate(self.conRed) } else{ NSLayoutConstraint.activate(self.conGreen) } // スワイプビュー:後ろに移動する self.view.insertSubview(sender.view!, at: 0) }) } } override func viewDidLoad() { super.viewDidLoad() // 赤ビュー red.backgroundColor = UIColor.red red.myDelegate = self view .addSubview(red) red.translatesAutoresizingMaskIntoConstraints = false let constRedA = red.topAnchor.constraint(equalTo: view.topAnchor, constant: 200) let constRedB = red.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 100) let constRedC = red.widthAnchor.constraint(equalToConstant: 200) let constRedD = red.heightAnchor.constraint(equalToConstant: 200) conRed = [constRedA, constRedB, constRedC, constRedD] // 赤ビューの初期制約セット NSLayoutConstraint.activate(conRed) // 緑ビュー green.backgroundColor = UIColor.green green.myDelegate = self view .addSubview(green) green.translatesAutoresizingMaskIntoConstraints = false let constGreenA = green.topAnchor.constraint(equalTo: view.topAnchor, constant: 200) let constGreenB = green.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -100) let constGreenC = green.widthAnchor.constraint(equalToConstant: 200) let constGreenD = green.heightAnchor.constraint(equalToConstant: 200) conGreen = [constGreenA, constGreenB, constGreenC, constGreenD] // 緑ビューの初期制約セット NSLayoutConstraint.activate(conGreen) } override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() }

}

補足情報(FW/ツールのバージョンなど)

iOS12.1.4
xcode 10.1
swift 4.2

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fuzzball

2019/02/27 03:45

コードは ``` で囲って下さい。
guest

回答1

0

ベストアンサー

すみません、他サイトで回答を得られ、解決しました。
閉じるを押して、縮小するときに拡大ジェスチャも同時に走っていたことが原因でした。
ですので、クローズいたします。

fuzzballさん、ご指摘ありがとうございます。
次回から気をつけます。

投稿2019/02/27 08:58

編集2019/02/27 09:00
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fuzzball

2019/02/27 09:05

次からじゃなくて今直したらどうですか? もう解決したからどうでもいいですか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問