• override func viewWillDisappear(_ animated: Bool) {  super.viewWillDisappear(animated)  navigationController?.interactivePopGestureRecognizer?.isEnabled = true;  }

      

    问题原因:

    当时项目有侧滑功能,还有push的动画 和系统本来的侧滑返回,---这三个东西在你频繁操作的时候会偶发,最终造成界面卡死。


    会出现侧滑异常,这里就吧侧滑返回功能给禁止了。


      overridefunc viewWillDisappear(_ animated:Bool) {

            super.viewWillDisappear(animated)

            navigationController?.interactivePopGestureRecognizer?.isEnabled =true;


        }

        

        overridefunc viewDidAppear(_ animated:Bool) {

            navigationController?.interactivePopGestureRecognizer?.isEnabled =false;


        }

        

    展开全文
  • swift 手势

    2018-05-23 17:38:22
    边缘手势 import UIKit class ScreenEdgePanGestureViewController: UIViewController { var tesView:UIView? override func viewDidLoad() { super.viewDidLoad() self.view.backgroundC...

    滑动(快速移动)

    mport UIKit
    
    class ViewController: UIViewController {
    
        var testView:UIView?
        override func viewDidLoad() {
            super.viewDidLoad()
            self.view.backgroundColor = UIColor.yellow
            let testView = UIView(frame: CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: self.view.frame.size.height))
            testView.backgroundColor = UIColor.red
            self.testView = testView
            self.view.addSubview(testView)
            let swipeLeft = UISwipeGestureRecognizer(target: self, action: #selector(self.mySwipe))
            swipeLeft.direction = .left
       self.view.addGestureRecognizer(swipeLeft)
            let swipeRight = UISwipeGestureRecognizer(target: self, action: #selector(self.mySwipe))
            swipeRight.direction = .right
        self.view.addGestureRecognizer(swipeRight)
            let swipeUp = UISwipeGestureRecognizer(target: self, action: #selector(self.mySwipe))
            swipeUp.direction = .up
        self.view.addGestureRecognizer(swipeUp)
            let swipeDown = UISwipeGestureRecognizer(target: self, action: #selector(self.mySwipe))
            swipeDown.direction = .down      self.view.addGestureRecognizer(swipeDown)   
        }
        fileprivate func panGesture(){
            let panVC = PanGestureViewController()
             self.navigationController?.pushViewController(panVC, animated: true)
        }
        @objc func mySwipe(recognizer:UISwipeGestureRecognizer) {
            UIView.animate(withDuration: 5) {
            switch recognizer.direction {
                case .left:
                    print("leftleftleftleftleftleft")
                     self.testView?.frame = CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: self.view.frame.size.height)
                case .right:
                    print("rightrightrightrightright")
                    self.testView?.frame = CGRect(x: self.view.frame.size.width, y: 0, width: self.view.frame.size.width, height: self.view.frame.size.height)
                case .up:
                    print("upupupupup")
                    self.testView?.frame = CGRect(x: 0, y: -200, width: self.view.frame.size.width, height: self.view.frame.size.height)
                case .down:
                    print("downdowndowndown")
                    self.testView?.frame = CGRect(x: 0, y: 200, width: self.view.frame.size.width, height: self.view.frame.size.height)
            default:
                print("aa")
                }
            }
        }
    }
    
    

    边缘手势

    import UIKit
    class ScreenEdgePanGestureViewController: UIViewController {
    
    
        var tesView:UIView?
        override func viewDidLoad() {
            super.viewDidLoad()
    
            self.view.backgroundColor = UIColor.blue
            let testView = UIView(frame: CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: self.view.frame.size.height))
            testView.backgroundColor = UIColor.orange
            self.tesView = testView
            self.view.addSubview(testView)
           // 边缘滑动
            let swipe = UIScreenEdgePanGestureRecognizer(target: self, action: #selector(self.myScreenSwipe(_:)))
            swipe.edges = .left
            swipe.maximumNumberOfTouches = 1
            self.view.addGestureRecognizer(swipe)
    
            let swipeRight = UIScreenEdgePanGestureRecognizer(target: self, action: #selector(self.myScreenSwipe(_:)))
            swipeRight.edges = .right
            swipeRight.maximumNumberOfTouches = 1
            self.view.addGestureRecognizer(swipeRight)
    
            let swipeTop = UIScreenEdgePanGestureRecognizer(target: self, action: #selector(self.myScreenSwipe(_:)))
            swipeTop.edges = .top
            swipeTop.maximumNumberOfTouches = 1
            self.view.addGestureRecognizer(swipeTop)
    
            let swipeBottom = UIScreenEdgePanGestureRecognizer(target: self, action: #selector(self.myScreenSwipe(_:)))
            swipeBottom.edges = .bottom
            swipeBottom.maximumNumberOfTouches = 1
            self.view.addGestureRecognizer(swipeBottom)
    
        }
    
        override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
            UIView.animate(withDuration: 5) {
                 self.tesView?.frame = CGRect(x:0, y: 0, width: self.view.frame.size.width, height: self.view.frame.size.height)
            }
        }
    
    
        @objc func myScreenSwipe(_ recognizer:UIScreenEdgePanGestureRecognizer) {
    
            UIView.animate(withDuration: 5) {
            switch recognizer.edges {
    
            case .left:
                print("leftleftleftleftleftleft")
             self.tesView?.frame = CGRect(x:200, y: 0, width: self.view.frame.size.width, height: self.view.frame.size.height)
            case .right:
                print("rightrightrightrightright")
    
                 self.tesView?.frame = CGRect(x: -200, y: 0, width: self.view.frame.size.width, height: self.view.frame.size.height)
            case .top:
                print("toptoptoptoptoptop")
                // 一定要注意 Top and Bottom Edge Gestures trigger 20 Pixels from the screen Edge.
               // By default the status bar is Visible and takes the top 20 pixels space so you must hide the status bar to use these (top / bot) UIScreenEdgePanGestureRecognizers, or else the delegate does Not get called.
                 self.tesView?.frame = CGRect(x: 0, y: 200, width: self.view.frame.size.width, height: self.view.frame.size.height)
            case .bottom:
                print("bottombottombottombottombottom")
    
                self.tesView?.frame = CGRect(x: 0, y: -200, width: self.view.frame.size.width, height: self.view.frame.size.height)
            default:
                print("aa")
    
              }
            }
        }
    
        //Top and Bottom Edge Gestures trigger 20 Pixels from the screen Edge.By default the status bar is Visible and takes the top 20 pixels space so you must hide the status bar to use these (top / bot) UIScreenEdgePanGestureRecognizers, or else the delegate does Not get called.
        override var prefersStatusBarHidden: Bool{
            print("隐藏")
            return true
        }
        // 设置后下拉状态栏只会展示指示器,继续下拉才能将通知中心拉出来。如果返回UIRectEdgeNone则会直接下拉出来。
        override func preferredScreenEdgesDeferringSystemGestures() -> UIRectEdge {
            print("屏幕手势上下左右都响应")
            return UIRectEdge.all
        }
    
    }
    

    轻拍手势

     import UIKit
    
    class TapGestureViewController: UIViewController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
            self.view.backgroundColor = UIColor.lightGray
            // 轻拍手势
            let tapSingle = UITapGestureRecognizer(target: self, action: #selector(self.myTapSingle))
            //可以通过 numberOfTouchesRequired 属性设置触摸点数,比如设置 2 表示必须两个手指触摸时才会触发
            tapSingle.numberOfTouchesRequired = 1
            // 通过 numberOfTapsRequired 属性设置点击次数,单击设置为 1,双击设置为 2
            tapSingle.numberOfTapsRequired = 1
    
            let tapDouble = UITapGestureRecognizer(target: self, action: #selector(self.myTapDouble))
            tapDouble.numberOfTouchesRequired = 2
            tapDouble.numberOfTapsRequired = 2
            //如果一个控件既监听了单击事件也监听了双击事件,默认当双击事件触发的时候也同时会触发单击事件。如果想双击时不触发单击,需要通过 require(toFail:) 进行设置
            tapSingle.require(toFail: tapDouble)
            self.view.addGestureRecognizer(tapSingle)
            self.view.addGestureRecognizer(tapDouble)
        }
    
    
        @objc func myTapSingle(_ recognizer:UITapGestureRecognizer){
            print("一个指头单击事件")
        }
        @objc func myTapDouble(_ recognizer:UITapGestureRecognizer){
            print("两个指头双击事件")
        }
    
    }

    拖拽手势

    import UIKit
    
    class PanGestureViewController: UIViewController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
           self.view.backgroundColor = UIColor.darkText
            let rectView = UIView(frame:CGRect(x:0, y:0, width:100, height:100))
            rectView.center = self.view.center
            rectView.backgroundColor = UIColor.orange
            //由于一个GestureRecognizer只能对应一个view,这里定义两个GestureRecognizer
            // 拖拽手势
            let pan = UIPanGestureRecognizer(target:self,action:#selector(panDid))
            pan.maximumNumberOfTouches = 1
            pan.minimumNumberOfTouches = 1
            rectView.addGestureRecognizer(pan)
            self.view.addSubview(rectView)
    
        }
        // 跟随指头的指向点一直拖拽
        @objc func panDid(_ recognizer:UIPanGestureRecognizer){
            let point=recognizer.location(in: self.view)
            //设置矩形的位置
            recognizer.view?.center = point
        }
    }
    展开全文
  • 如何在ScrollView滑动的瞬间禁用拖拽手势 效果: 在UIScrollView滑动的瞬间禁用pan手势,可以防止用户按着屏幕不放后导致出现的一些莫须有的bug. // // ViewController.m // TableViewDemo // // Created...

    如何在ScrollView滑动的瞬间禁用拖拽手势

    效果:

    在UIScrollView滑动的瞬间禁用pan手势,可以防止用户按着屏幕不放后导致出现的一些莫须有的bug.

    //
    //  ViewController.m
    //  TableViewDemo
    //
    //  Created by XianMingYou on 15/2/23.
    //  Copyright (c) 2015年 XianMingYou. All rights reserved.
    //
    
    #import "ViewController.h"
    
    @interface ViewController ()<UITableViewDelegate, UITableViewDataSource>
    
    @property (nonatomic, strong) UITableView *tableView;
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        self.tableView = [[UITableView alloc] initWithFrame:self.view.bounds
                                                      style:UITableViewStylePlain];
        self.tableView.delegate   = self;
        self.tableView.dataSource = self;
        [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"YouXianMing"];
     
        [self.view addSubview:self.tableView];
    }
    
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
        return 3;
    }
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"YouXianMing"];
        cell.textLabel.text   = @"YouXianMing";
        return cell;
    }
    - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
        
        CGFloat offsetY = scrollView.contentOffset.y;
        
        if (offsetY <= -100) {
            // 存储这一瞬间的contentOffset值
            CGPoint storePoint = scrollView.contentOffset;
            
            // 禁止用pan手势(禁用pan手势瞬间会导致contenOffset值瞬间恢复成(0, 0))
            scrollView.panGestureRecognizer.enabled = NO;
            
            // 设置此时的contentOffset值
            scrollView.contentOffset = storePoint;
            
            [UIView animateWithDuration:0.5 animations:^{
                // 动画过渡
                scrollView.contentOffset = CGPointMake(0, 0);
            } completion:^(BOOL finished) {
                // 恢复手势
                scrollView.panGestureRecognizer.enabled = YES;
            }];
        }
    }
    
    @end

    关键的一步:

    (禁用手势后,需要存储当时的contentOffset值,然后再重设,用动画过渡即可)

     

    展开全文
  • 一、有时候只是想简单的显示播放进度,不想让Slider可以拖动,做法其实很简单,只用一下两步就可以了: 1、建立一个继承自UISlider的子类。 2、在新建的子类中添加下面这...以上方法可以禁止slider的拖动,如果想...

    一、有时候只是想简单的显示播放进度,不想让Slider可以拖动,做法其实很简单,只用一下两步就可以了:

    1、建立一个继承自UISlider的子类。

    2、在新建的子类中添加下面这个方法:

    - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
        return NO;
    }

    以上方法可以禁止slider的拖动,如果想隐藏拖动的小圆点,可以设置slider的这个属性:

    slider.thumbTintColor = [UIColor clearColor];

    这样就实现slider只显示,不拖动的功能。

     

    二、想要改变滑块的大小也很简单:

    1、改变滑块显示的大小:

    [slider setThumbImage:[UIImage imageNamed:@"slider"] forState:UIControlStateNormal];

    2、改变滑块滑动时的大小:

    [slider setThumbImage:[UIImage imageNamed:@"slider"] forState:UIControlStateHighlighted];

    另:这只是我自己的做法,不一定是最佳的方案,只是一个可实现功能的简单方案。

    展开全文
  • 初步实现了一个防今日头条的频道管理,能够进行拖拽排序,效果图如下 分析 主要使用UICollectionView实现,利用其原生的API实现拖拽效果。 核心分为以下步骤: - 得到获取焦点的Cell - 处理移动中的事件 ...

    前言

    初步实现了一个仿今日头条的频道管理,能够进行拖拽排序,效果图如下

    这里写图片描述

    分析

    主要使用UICollectionView实现,利用其原生的API实现拖拽效果。

    核心分为以下步骤:
    - 得到获取焦点的Cell
    - 处理移动中的事件
    - 移动结束后,处理放下Cell问题

    创建UICollectionView之前先创建个UICollectionViewFlowLayout,我们定义一行最多显示4个Cell,单个Cell之前的间距是10,高度为40

    let width: CGFloat = (self.view.frame.width -  5 * 10) / 4
    let height: CGFloat = 40

    定义UICollectionViewFlowLayout

    let flowLayout = UICollectionViewFlowLayout()
    //滚动方向
    flowLayout.scrollDirection = .vertical
    //网格中各行项目之间使用的最小间距
    flowLayout.minimumLineSpacing = 10
    //在同一行中的项目之间使用的最小间距
    flowLayout.minimumInteritemSpacing = 10
    //用于单元格的默认大小
    flowLayout.itemSize = CGSize.init(width: width, height: height)
    //用于标题的默认大小
    flowLayout.headerReferenceSize = CGSize.init(width: self.view.frame.width, height: 50)

    headerReferenceSize 用于定义头部的大小(IndexPath.section对应的部分)

    创建UICollectionView,UICollectionView需要register两个,一个是普通视图的Cell,一个是头部对应的Cell

    myCollectionView = UICollectionView(frame: .zero, collectionViewLayout: flowLayout)
    myCollectionView.register(UINib.init(nibName: "EditCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: EditCollectionViewCell.forCellReuseIdentifier)
    myCollectionView.register(UINib(nibName: "HeaderCollectionReusableView", bundle: nil), forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: HeaderCollectionReusableView.forCellReuseIdentifier)

    EditCollectionViewCell 为频道的Cell(如:“关注、特产、健康、房产等”),HeaderCollectionReusableView 为头部的Cell (如:“我的频道、频道推荐”)

    需要实现的代理

    myCollectionView.delegate = self
    myCollectionView.dataSource = self
    myCollectionView.dragDelegate = self
    myCollectionView.dropDelegate = self

    delegate 管理集合视图中项目显示和选择
    dataSource 提供数据源
    dragDelegate 管理拖曳交互
    dropDelegate 管理丢弃交互
    重点就是dragDelegate和dropDelegate

    提供的数据源如下

     func initData() {
            itemHeaders = ["我的频道","频道推荐"]
            itemNames = [0: [String](["关注","推荐","视频","热点","北京","新时代","图片","头条号","娱乐","问答","体育","科技","懂车帝","财经","军事","国际"]),1: [String](["健康","冬奥","特产","房产","小说","时尚","历史","育儿","直播","搞笑","数码","美食","养生","电影","手机","旅游","宠物","情感"])]
    
        }

    开启UICollectionView响应拖拽操作

    myCollectionView.dragInteractionEnabled = true

    以上是基本的操作流程,下面重点讲下,上边提到的三个步骤


    得到获取焦点的Cell

    需要实现UICollectionViewDragDelegate代理,并提供UIDragItem

    func collectionView(_ collectionView: UICollectionView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] {
            guard indexPath.section != 1 else {
                return []
            }
            let item = self.itemNames[indexPath.section]![indexPath.row]
            let itemProvider = NSItemProvider(object: item as NSString)
            let dragItem = UIDragItem(itemProvider: itemProvider)
            dragItem.localObject = item
            dragingIndexPath = indexPath
            return [dragItem]
        }

    由于我们规定,“我的频道”可以拖拽,“频道推荐”不可以,所以 indexPath.section 为1 的部分,返回一个空数组,表示不响应事件。
    通过section和row 获取到对象的值,并创建NSItemProvider返回。

    NSItemProvider:拖放活动期间在进程之间共享的数据或文件,初始化的object要是NSObject, NSCopying的子类,如:NSItemProvider(object: item as NSString),是把String作为共享数据了。

    处理移动中的事件

    这个我们需要实现UICollectionViewDropDelegate代理,并提供UICollectionViewDropProposal

    func collectionView(_ collectionView: UICollectionView, dropSessionDidUpdate session: UIDropSession, withDestinationIndexPath destinationIndexPath: IndexPath?) -> UICollectionViewDropProposal {
            guard dragingIndexPath?.section == destinationIndexPath?.section else {
                return UICollectionViewDropProposal(operation: .forbidden)
            }
            if session.localDragSession != nil {
                if collectionView.hasActiveDrag {
                    return UICollectionViewDropProposal(operation: .move, intent: .insertAtDestinationIndexPath)
                } else {
                    return UICollectionViewDropProposal(operation: .copy, intent: .insertAtDestinationIndexPath)
                }
            } else {
                return UICollectionViewDropProposal(operation: .forbidden)
            }
        }

    由于“我的频道”和“频道推荐”是禁止互相滑动的,所以,拖拽的起始dragingIndexPath和目标destinationIndexPath的section不一样,就表示跨区了,设置其为forbidden。

    移动结束后,处理放下Cell问题

    这是最后一步,需要实现UICollectionViewDropDelegate代理,通过coordinator我们可以获取到操作类型,是move还是copy。

    func collectionView(_ collectionView: UICollectionView, performDropWith coordinator: UICollectionViewDropCoordinator) {
            guard let destinationIndexPath = coordinator.destinationIndexPath else {
                return
            }
            switch coordinator.proposal.operation {
            case .move: 
                break
            case .copy:
    
                break
            default:
                return
            }
        }

    move 操作后,需要把之前的位置删除掉,在新的位置进行插入

    self.itemNames[destinationIndexPath.section]!.remove(at: sourceIndexPath.row)
    self.itemNames[destinationIndexPath.section]!.insert(item.dragItem.localObject as! String, at: destinationIndexPath.row)
    collectionView.deleteItems(at: [sourceIndexPath])
    collectionView.insertItems(at: [destinationIndexPath])

    要先对数据源进行移除和添加操作,然后在视图进行更新,否则会崩溃

    copy 操作后,需要在新的位置进行插入

    let indexPath = IndexPath(row: destinationIndexPath.row, section: destinationIndexPath.section)
    self.itemNames[destinationIndexPath.section]!.insert(item.dragItem.localObject as! String, at: indexPath.row)
    collectionView.insertItems(at: indexPath)

    以上就是全部的分析流程,还有一种实现思路是:在collectionView上添加一个自定义的View,覆盖在Cell之上,获取手势事件后,根据手势滑动,动态更改自定义的View的位置,同样可以实现以上效果。

    Git: https://github.com/LSnumber1/CustomUICollection

    展开全文
  • 最近"铃声多多"项目里遇到一个需求,在小视频里加上评论功能,要求和抖音的评论功能有一样的手势拖拽效果. 刚开始想着直接上网抄一个就行了,所以在github,CocoaChina,Coccoa4App上找了一圈,包括有些已经几千个star的...
  • 父视图要实现手势协议UIGestureRecognizerDelegate - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch { if ([touch.view isDescendantOfView:想要哪个...
  • 项目中要实现在UIPageViewController嵌套UIScrollview,所以存在侧滑冲突 禁用其翻页手势,代码如下: self.pageViewController.dataSource = nil;
  • 一.效果图 二.核心方法 1.在iOS 9之后系统提供了一套API用于实现重排 // Support for reordering - (BOOL)beginInteractiveMovementForItemAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(9_0);...
  • 允许子视图手势延时响应 ...以上设置了只是达到停顿0.5秒后,子控件可以手势拖动 如果想直接响应,重写ScrollView 的 touches方法,判断传入的视图 而后使用- (BOOL)touchesShouldCancelInContentView:(UIView
  • 给父视图上添加一个子视图,给父视图添加一个手势识别器UITapGestureRecognizer,点击子视图时,也会触发UITapGestureRecognizer所关联的事件 代码: UIView *blackV = [[UIView alloc]initWithFrame:CGRectMake...
  • navigationController(导航控制器)的view自带了滑动手势,只要在屏幕左侧向右拖动页面,就可以滑动返回到前面一个页面。但这个功能仅在屏幕左侧边缘滑动才能触发,我们可以稍作改造,让其支持全屏滑动返回。 ...
  • 效果图 详解 概览 页面构成:地图视图mapVC , 资源信息视图soureVC(视图控制器的view上放了一个UITableView)。 动画效果: 1. 上滑:soureVC通过滑动慢慢上移,到达...首先我们肯定是给sourceVC的view上添加平移手势...
  • 2019独角兽企业重金招聘Python工程师标准>>> ...
  • //创建滚动视图  let scrollView = UIScrollView()    //设置尺寸  scrollView.frame = CGRectMake(0, 100, self.view.frame.size.width, 200)    //设置背景色
  • 原文地址:http://www.raywenderlich.com/74904/swift-tutorial-part-2-simple-ios-app 泰然翻译组:永远的微笑。校对:gloryming。...在第一个Swift教程中,你们学习了Swift语言的基础语法,并创建了自己的小费计
  • 设置状态栏样式 [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleDefault; [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleLightContent; 状态栏加载指示器 ...
  • UISlider无法拖动进度条的问题解决 最近业务中的视频播放使用到了UISlider,但是有一个奇怪的问题,就是在Modar出来的控制器中UISlider是可以正常使用的,但是在Push出来的控制器,其在最开的屏幕边缘,大概20点...
  • 今天在用这个导航栏的时候发现一个问题,UIPanGestureRecognizer是任何滑动手势都会辨别,它不像UISwipeGestureRecognizer一样有方向.这样在有些情况下会产生问题。
  • 解决ios滑动穿透问题

    2019-12-16 10:47:36
    function closest(el, selector) { const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector; while (el) { if (matchesSelector.call(el, sel...
1 2 3 4 5 6
收藏数 120
精华内容 48
关键字:

swift 禁止拖动手势