1

So I've got two views, both added to the superview programmatically:

//First added view to my superView (baseView)
let imageViewOne = UIImageView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
baseView.addSubview(imageViewOne)
//Second added view to my superView (baseView)
let imageViewTwo = UIImageView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
baseView.addSubview(imageViewTwo)

I want to bring one of them to the front when it is selected because when you add a new view, it overlaps the previous one. Something that works with "selected" or "touched".

VijayD
  • 826
  • 1
  • 11
  • 33
ciklukylok
  • 47
  • 1
  • 13
  • Please refer this link: https://stackoverflow.com/questions/38780743/how-can-i-bring-a-view-in-front-of-another-view-in-swift – Khushbu May 28 '18 at 12:35
  • Yes I have already read that article but it's clearly not what I need. I need the view to be brought to front merely after it is selected or touched. – ciklukylok May 28 '18 at 12:39

3 Answers3

4

Use this:

baseView.bringSubview(toFront: imageViewOne)
Tom E
  • 1,530
  • 9
  • 17
1

You can do this by UITapGestureRecognizer by setting Restoration ID from the interface builder

func tapOneAct(sender: UITapGestureRecognizer) {
    if(sender.view!.restorationIdentifier == "view1") 
    // view1 is `Restoration ID` of imageViewOne
    {
        view.bringSubview(toFront: imageViewOne)
    }
    if(sender.view!.restorationIdentifier == "view2")
    // view2 is `Restoration ID` of 2nd view
    {
        view.bringSubview(toFront: imageViewTwo)
    }
}
umairhhhs
  • 400
  • 6
  • 19
1

If I understand correctly then you would like to check the status of selected view and bring it to the front of the view hierarchy. In this case you have to do following things:

1) track selection state, let it will be var isSelected: Bool in code snippet

2) hold a callback for an action when view is selected (you can use for example UIButton to observe tap event)

In following code snippet you can check the selection state when the view is touched.

BaseView implements logic for checking the state of SelectionView.

import UIKit

final class SelectionView<T: UIView>: UIView {

    var onTap: ((_ isSelected: Bool) -> ())?

    // MARK: - Private

    private let view: T
    private let button = UIButton(type: .custom)
    private var isSelected: Bool = false

    // MARK: - Init

    init(view: T) {
        self.view = view

        super.init(frame: .zero)

        setUp()
    }

    // MARK: - Private

    private func setUp() {
        addSubview(view)
        addSubview(button)

        button.addTarget(self, action: #selector(onButtonTap), for: .touchUpInside)
    }

    @objc private func onButtonTap() {
        isSelected = !isSelected

        onTap?(isSelected)
    }

    // MARK: - Layout

    override func layoutSubviews() {
        super.layoutSubviews()

        view.frame = bounds
        button.frame = bounds
    }

    override func sizeThatFits(_ size: CGSize) -> CGSize {
        return view.sizeThatFits(size)
    }

    // MARK: - Unused

    override init(frame: CGRect) {
        fatalError("init(frame:) has not been implemented")
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

final class BaseView: UIView {

    init() {
        super.init(frame: .zero)

        let views = [SelectionView(view: UIView()), SelectionView(view: UIView())]
        for view in views {
            view.onTap = { [weak self, weak view] isSelected in
                guard let selectedView = view
                    else { return }

                if isSelected {
                    self?.bringSubview(toFront: selectedView)
                }
            }
        }
    }

    // MARK: - Unused

    override init(frame: CGRect) {
        fatalError("init(frame:) has not been implemented")
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}
Vladimir Kaltyrin
  • 621
  • 1
  • 4
  • 16