Move views created dynamically

0

I'm doing a simple application in which different views are added dynamically (buttons, sliders, labels, etc) to a view that makes container.This already works, but the next step would be to move (drag) these views created To place them in the desired position on the screen. For this I have put a button in the navigation bar with double functionality, Edit and Run. I do not know how to get that in the run mode, the views respond normally (if it is a button, I can do tap, if it's a slider, you can change its position ..) but in edit mode only respond to Pan Gesture to be able to drag them, and even if a touch was made, they would not respond to their usual events, just to Pan, while the button is this in Edit.I had thought to put a panel (UIView) that will pass to the first position (.bringToFront ()), but the views below it still respond to the touch. If I put the panel's .userInteraction () to false, the views do not respond but the panel either ... I'll appreciate any orient acion.

    
asked by jose 20.09.2016 в 12:57
source

3 answers

0

Well at the end I made a small fudge that for lack of something better seems to work. First a transparent view of the same size as the view container:

let frame = container.frame
let panel = UIView(frame: frame);panel.tag = -1000
let panGesture = UIPanGestureRecognizer (target: self, action:#selector(pan(sender:)))
panel.addGestureRecognizer(panGesture)
view.addSubview(panel)

Then I go through all the views to see if any of them contain the same point as the one captured in the transparent panel at the beginning of the panGesture (.began)

@IBAction func pan(sender: UIPanGestureRecognizer) {
switch sender.state {
case .began :
  let p: CGPoint = sender.location(in: view.viewWithTag(-1000))
  for v in container.subviews {
    if v.frame.contains(p){
      selected = v
      difference.x = p.x - selected!.center.x
      difference.y = p.y - selected!.center.y
    }
  }
case .changed :
  let location = sender.location(in: view.viewWithTag(-1000))
  selected?.center.x = location.x - (difference.x)
  selected?.center.y = location.y - (difference.y)
case .ended :
  selected = nil
default:
  print("Gesture indefinido")
}
    
answered by 07.10.2016 / 16:18
source
0

To make this type of 'drags' you can use the UICollectionView that allows you to move cells and to interact with them, then through booleans you would indicate when they can move and when they do not.

If not, as you mention the problem is that while you edit the switch for example it still works the same, for this you could perhaps try to make while you are in edit mode the objects that are not interactible, with a switch.enabled or some of this.

    
answered by 22.09.2016 в 15:11
0

Sorry, but I have not had time before. I think you want to be able to move the elements where you want inside the screen and also work when you tap. I have something that I did once but it is in ObjC, I hope that this is what you want and that it will serve you. Basically you have to add the pan gesture to the view to be able to move what is in it. You must have access to the items in the view, I use a singleton to save, since I could have 2 or 30, you could also browse the items in the view

UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(hacenPan:)];
[self.view addGestureRecognizer:pan];

Now you have to do the bread action. For this you should go recognizing the states and save the item that you are moving

-(void)hacenPan:(UIPanGestureRecognizer *)pan{
static Figura *f;
//compruebo los estados del pan para saber si esta comenzando o terminando...
if ( pan.state == UIGestureRecognizerStateChanged) {
    //se esta moviendo
    CGPoint currentPosition = [pan locationInView:self.view];
    if ( f ) {
        CGRect fr=f.shape.frame;
        fr.origin.x=currentPosition.x;
        fr.origin.y=currentPosition.y;
        f.shape.frame=fr;
    }

} else if ( pan.state == UIGestureRecognizerStateBegan) {
    //comienza el pan, busco la figura que hay debajo
    CGPoint inicio =[pan locationInView:self.view];
    //comprobar si el punto pertenece a alguna vista existente
    f=[ArraySingleton buscaFiguraConElPunto:inicio];
} else if ( pan.state == UIGestureRecognizerStateEnded) {
    //termino el pan, elimino la fogura que tuviera guardada
    f=nil;
}

}

This what it does is when it begins to recognize the bread, it looks for where it has started and if there is a Figure in those coordinates. You should go saving somewhere where each figure is. I have it in a singleton because I decided so, but you can be an array in the controller or whatever you want and from there I have to keep the figure that you want to move, since this event will be called many times, so when move the anger finger by UIGestureRecognizerStateChanged and that's where you move the item to the new position of the finger, with this you can drag the items on the screen and stay where you lift your finger. In my case I always used the same type, which is Figure.

I hope that it is what you were looking for and that it will serve you

    
answered by 24.09.2016 в 13:24