• ios中创建可以拖动的view原理和实现详解


    有时候我们会需要在界面上拖动view;uiview是继承于uiresponder的,所以可以响应触摸相关的事件。

    重点是以下一组方法:

    - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 

    - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event

    - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event     // 触摸事件结束,如果你需要自动把view停靠到一个位置,实现这个方法

    - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event  //外界因素取消touch事件等,如进入电话,进行特别处理

    对于最上面两个方法是必须实现的,后面两个方法是用来做一些额外的需求或者处理使用,如果只是要实现拖动view可以不实现。

    思路1: 创建一个uiview(或者你需要的控件)的子类,在类中实现上述的方法。

    思路2:在你相应的viewcontroller中实现上述方法(在viewcontroller中持有你要拖动的view,这样才能控制它),也能实现类似的目的,但这样触摸的范围就会是整个viewcontroller的view,你需要在touchesBegan进行相应的判断(从UITouch中可以得到view的相关信息),才能实现固定在小窗口内部的触摸。

    两种思路都是可行的,根据你实际情况去做选择,都没有问题。

    以下是代码(子类方式的简单实现,你也可以进行相应修改放到viewcontroller中):

    @interface TouchEaglView()
    @property (assign, nonatomic) CGPoint beginpoint;
    @end
    @implementation TouchEaglView

    - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
    {
        UITouch *touch = [touches anyObject];
        self.beginpoint = [touch locationInView:self];
        [super touchesBegan:touches withEvent:event];
    }

    - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
    {
        UITouch *touch = [touches anyObject];
        CGPoint currentLocation = [touch locationInView:self];
        CGRect frame = self.frame;
        frame.origin.x += currentLocation.x - self.beginpoint.x;
        frame.origin.y += currentLocation.y - self.beginpoint.y;
        self.frame = frame;
    }

    上面的代码存在一个问题,那就是他的触摸移动范围包括了屏幕之外,你会发现你可以把view部分拖动到屏幕外部。那么我们需要一个高级一些的实现:

    注:这个版本是基于viewcontroller的实现,并未子类化view;self.localview是你持有的小窗口,beginpoint需要你在viewcontroller中自己定义

    - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
    {
        if (!self.isInView)    // 仅当取到touch的view是小窗口时,我们才响应触控,否则直接return
        {
            return;
        }
        
        UITouch *touch = [touches anyObject];
        CGPoint currentPosition = [touch locationInView:self.localView];
        //偏移量
        float offsetX = currentPosition.x - beginpoint.x;
        float offsetY = currentPosition.y - beginpoint.y;
        //移动后的中心坐标
        self.localView.center = CGPointMake(self.localView.center.x + offsetX, self.localView.center.y + offsetY);
        
        //x轴左右极限坐标
        if (self.localView.center.x > (self.localView.superview.frame.size.width-self.localView.frame.size.width/2))
        {
            CGFloat x = self.localView.superview.frame.size.width-self.localView.frame.size.width/2;
            self.localView.center = CGPointMake(x, self.localView.center.y + offsetY);
        }
        else if (self.localView.center.x < self.localView.frame.size.width/2)
        {
            CGFloat x = self.localView.frame.size.width/2;
            self.localView.center = CGPointMake(x, self.localView.center.y + offsetY);
        }
        
        //y轴上下极限坐标
        if (self.localView.center.y > (self.localView.superview.frame.size.height-self.localView.frame.size.height/2))
        {
            CGFloat x = self.localView.center.x;
            CGFloat y = self.localView.superview.frame.size.height-self.localView.frame.size.height/2;
            self.localView.center = CGPointMake(x, y);
        }
        else if (self.localView.center.y <= self.localView.frame.size.height/2)
        {
            CGFloat x = self.localView.center.x;
            CGFloat y = self.localView.frame.size.height/2;
            self.localView.center = CGPointMake(x, y);
        }
    }


    - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
    {
        UITouch *touch = [touches anyObject];
        if (touch.view.frame.size.width == 120)   // 120为小窗口的宽度(简单起见这里使用硬编码示例),用来判断触控范围;仅当取到touch的view是小窗口时,我们才响应触控
        {
            self.isInView = YES;
        }
        else
        {
            self.isInView = NO;
        }
        beginpoint = [touch locationInView:self.localView];
        
        [super touchesBegan:touches withEvent:event];
    }

    原文:http://www.codesocang.com/jiaocheng/shoujikaifa/2014/0430/7233.html

  • 相关阅读:
    dotnet 控制台读写 Sqlite 提示 no such table 找不到文件
    dotnet 控制台读写 Sqlite 提示 no such table 找不到文件
    dotnet 控制台 Hangfire 后台定时任务
    dotnet 控制台 Hangfire 后台定时任务
    dotnet 获取指定进程的输入命令行
    dotnet 获取指定进程的输入命令行
    PHP sqrt() 函数
    PHP sinh() 函数
    PHP sin() 函数
    PHP round() 函数
  • 原文地址:https://www.cnblogs.com/miaoqing/p/3758584.html
Copyright © 2020-2023  润新知