Search code examples
iosswiftuimenuitem

How can I set a button on the selected position of the view?


I'm very new to iOS development, but I'm struggling with the view's position thing.

On a single view controller, I tried to make a circle on the view by long-pressing the view but I can only make it at the center of the view. Do you know how to make a circle where I picked?

override func viewDidLoad() {
    super.viewDidLoad()
    view.backgroundColor = .white

    longPressView()
}

let addCircle = UIButton()
let circleAddDefaultSize: Int = 10

func longPressView() {
    let longPress = UILongPressGestureRecognizer(target: self, action: #selector(longPressForView))
    view.addGestureRecognizer(longPress)
}

override var canBecomeFirstResponder: Bool {
    return true
}

//Long press then MenuItem comes up
@objc func longPressForView(sender: UILongPressGestureRecognizer) {
    if sender.state == .began {
        let menu = UIMenuController.shared
        becomeFirstResponder()

        let menuItemAdd = UIMenuItem(title: "Add", action: #selector(addCircleMenuItemAction))
        let menuItemDelete = UIMenuItem(title: "Delete", action: #selector(handleMenuItemAction))
        menu.menuItems = [menuItemAdd, menuItemDelete]

        //I want to use this location in addCircleMenuItemAction()
        let location = sender.location(in: sender.view)
        let menuLocation = CGRect(x: location.x, y: location.y, width: 0, height: 0)
        menu.showMenu(from: sender.view!, rect: menuLocation)
    }
}

//Press add button and I want to add a button on that location
@objc func addCircleMenuItemAction() {

    print("Add item tapped")

    view.addSubview(addCircle)
    addCircle.layer.cornerRadius = CGFloat(circleAddDefaultSize/2)
    addCircle.translatesAutoresizingMaskIntoConstraints = false
    addCircle.backgroundColor = .black
    //Create constraints 
    //Instead of using this center constraints, how can I use the location from longPressForView() ?
    let centerX = NSLayoutConstraint(item: addCircle, attribute: .centerX, relatedBy: .equal, toItem: view, attribute: .centerX, multiplier: 1, constant: 0)
    let centerY = NSLayoutConstraint(item: addCircle, attribute: .centerY, relatedBy: .equal, toItem: view, attribute: .centerY, multiplier: 1, constant: 0)
    addCircle.widthAnchor.constraint(equalToConstant: CGFloat(circleAddDefaultSize)).isActive = true
    addCircle.heightAnchor.constraint(equalToConstant: CGFloat(circleAddDefaultSize)).isActive = true
    addCircle.isUserInteractionEnabled = true
    view.addConstraints([centerX, centerY])

}

When I run this, I can only put the circle button on the center of the view.


Solution

  • you are setting constraints to centre of your view

    let centerX = NSLayoutConstraint(item: addCircle, attribute: .centerX, relatedBy: .equal, toItem: view, attribute: .centerX, multiplier: 1, constant: 0)
    let centerY = NSLayoutConstraint(item: addCircle, attribute: .centerY, relatedBy: .equal, toItem: view, attribute: .centerY, multiplier: 1, constant: 0)
    

    thats why it will always show in center

    instead of constraints do something like this

    @objc func addCircleMenuItemAction(center:CGPoint) {
    
            print("Add item tapped")
    
            view.addSubview(addCircle)
            addCircle.frame = CGRect(origin: .zero, size: CGSize(width: circleAddDefaultSize,height: circleAddDefaultSize))
            addCircle.center = center
            addCircle.backgroundColor = .black
            addCircle.isUserInteractionEnabled = true
    
        }