前提・実現したいこと
300×300のマップビューの上に
100×100のビューを表示しております。
ここで、
100×100のビューをタップしたら、
300×300にビューの大きさを変更し、
マップビューを
100×100の大きさにして、
ビューとマップビューの前後を変更(マップビューをビューの上に描画)したいのですが、
100×100のビューをタップすると、ビューが消えてしまい、マップビューの大きさも変わりません。
この状態から、マップビューを300×300の状態をタップすると100×100のビューが表示されます(おそらくきちんと動作している)。
実現したいことは、ビューとマップビューの小さい方をタップすると、タップされた方を拡大して後ろ側に、されていない方が小さくなって前面に来る。ということを実現したいです。
発生している問題・エラーメッセージ
bringSubviewToFrontとsendSubviewToBackが上手く機能しない
該当のソースコード
@IBOutlet weak var parentView: UIView! // 親
@IBOutlet weak var mapView : MKMapView! // マップ
@IBOutlet weak var childView : UIView! // ビュー
/// 画面表示直前に呼ばれる
override func viewWillAppear(animated : Bool) {
super.viewWillAppear(animated)
// 親ビューの子供に設定
self.parentView.addSubview(self.mapView)
self.parentView.addSubview(self.childView)
}
// マップビュー拡大(正しく動いている?)
@IBAction func ChangeMapView(sender: AnyObject) {
self.mapView.frame = CGRect(x: 0, y: 0, width: 300, height: 300)
self.childView.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
self.parentView.sendSubviewToBack(self.mapView)
self.parentView.bringSubviewToFront(self.childView)
}
// ビュー拡大(ビューが消える)
@IBAction func ChangeChildView(sender: AnyObject) {
self.childView.frame = CGRect(x: 0, y: 0, width: 300, height: 300)
self.mapView.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
self.parentView.sendSubviewToBack(self.childView)
self.parentView.bringSubviewToFront(self.mapView)
}
試したこと
大きさがかぶっているため表示されないのかと思い、ビューの大きさを変更して400×400等にしたが、表示がされない。
parentViewを使用せず、最初からあるself.viewにmapViewとchildViewをaddChildしてみたりしたが、挙動に変更がありませんでした。
補足情報(言語/FW/ツール等のバージョンなど)
swift2.3
Xcode7.3.1
アドバイスを受け修正したコードになります。
@IBAction func ChangeMapView(sender: AnyObject) {
self.mapView.frame = CGRect(x: 100, y: 1, width: 400, height: 400)
self.childView.frame = CGRect(x: 1, y: 1, width: 200, height: 200)
self.parentView.bringSubviewToFront(self.childView)
}
@IBAction func ChangeChildView(sender: AnyObject) {
self.childView.frame = CGRect(x: 1, y: 1, width: 400, height: 400)
self.mapView.frame = CGRect(x: 1, y: 1, width: 200, height: 200)
self.parentView.bringSubviewToFront(self.mapView)
}
解決したコード
// 親のビュー
@IBOutlet weak var parentView: UIView!
// 描画順を変更したいビュー
var mapView : MKMapView! = MKMapView()
var childView : UIView! = UIView()
override func viewWillAppear(animated : Bool) {
super.viewWillAppear(animated)
// サブビューに追加
parentView.addSubview(self.mapView)
parentView.addSubview(self.childView)
// 大きさの初期値
self.mapView.frame = CGRect(x: 0,y: 0,width: 100,height: 100)
self.childView.frame = CGRect(x: 110,y: 0,width: 100,height: 100)
// タップできるようにする
self.mapView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(ChangeMapView)))
self.childView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(ChangeChildView)))
}
// childViewを縮小して前面に
func ChangeMapView(sender: AnyObject) {
self.mapView.frame = CGRect(x: 100, y: 1, width: 400, height: 400)
self.childView.frame = CGRect(x: 1, y: 1, width: 200, height: 200)
self.parentView.bringSubviewToFront(self.childView)
}
// mapViewを縮小して前面に
func ChangeChildView(sender: AnyObject) {
self.childView.frame = CGRect(x: 1, y: 1, width: 400, height: 400)
self.mapView.frame = CGRect(x: 1, y: 1, width: 200, height: 200)
self.parentView.bringSubviewToFront(self.mapView)
}
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
checkベストアンサー
0
// 親ビューの子供に設定
self.parentView.addSubview(self.mapView)
self.parentView.addSubview(self.childView)
Storyboardで配置しているのですから、このコードは必要ないのでは?
画面に見えているのはコードで追加したViewで、タップした時にサイズ/優先を変更しているのはStoryboardで配置したViewになっていると思います。
おまけ
上に来るViewを最前面に表示させればいいのでself.view.sendSubviewToBack()
は不要です。
おまけ2
タップ時はフラグを変更してレイアウト更新を依頼する。
実際のレイアウト変更はviewDidLayoutSubviews()で行う。
この方法だと、Storyboardを使っていても大丈夫だと思います。
var isMap = true
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
if isMap {
//childを縮小して上に、mapは拡大
} else {
//mapを縮小して上に、childは拡大
}
}
@IBAction func ChangeMapView(sender: AnyObject) {
isMap = true
self.view.setNeedsLayout()
}
@IBAction func ChangeChildView(sender: AnyObject) {
isMap = false
self.view.setNeedsLayout()
}
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.10%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
質問への追記・修正、ベストアンサー選択の依頼
fuzzball
2017/02/28 09:05 編集
(deleted)