(作业)View,Layer,Animation和Gesture

Android 视频手势缩放与回弹动效实现(一) 文章目录Android 视频播放画面手势缩放与缩放后自动吸附动效实现1. 功能需求2. 实现原理2.1 如何检测手势缩放?1. View.onTouchEvent关键代码2. ScaleGestureDetector2.2 缩放平移处理2.3 暂停画面下缩放2.4 缩放移动结束后动效1. 缩小居中2. 放大吸边3. 项目完整代码3.1 手势缩放处理:VideoTouchScaleHandler3.2 动画:VideoScaleEndAnimator Android 视频播放画面手势缩放与缩放后自动吸附动效实 阅读详情

又开始做作业了,这次虽然设计的知识点比较多,但是都比较简单,一个页面就能完成。先来看看要求吧
这里写图片描述

根据这个要求,我们先要自定制一个视图,所以需要新建一个继承自UIView的类,这里博主就使用MyView来命名。
然后在这个类中,我们需要先重写它的draw(_:)方法。

override func draw(_ rect: CGRect) {
        let viewRect = UIBezierPath(rect: rect)

        let redColor = CGFloat(Float(arc4random() % 255) / 255)
        let greenColor = CGFloat(Float(arc4random() % 255) / 255)
        let blueColor = CGFloat(Float(arc4random() % 255) / 255)

        UIColor(red: redColor, green: greenColor, blue: blueColor, alpha: 1.0).set()

        viewRect.stroke()
        viewRect.fill()
    }

在这个代码中,我们使用arc4random()方法来生成一个随机数,这个方法会返回一个UInt32的随机数,然后使用这个方法来生成rgb颜色,使用该颜色填充和描边矩形区域。

然后我们需要重写一个初始化函数

override init(frame: CGRect) {
        super.init(frame: frame)

        setup()
    }

因为如果子类自己重写了初始化函数的话,也必须实现UIView的另一个初始化函数,但我们需要在初始化函数中对自定义的视图类加一些功能,所以我们就把这些添加的功能放在一个setup()方法当中了。必须实现的初始化方法如下:

required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)

        setup()
    }

在这个setup()方法中,我们可以设置视图的阴影并添加要求的手势

func setup() {
        //设置矩形区域圆角
        self.layer.cornerRadius = 20
        //设置阴影
        self.layer.shadowColor = UIColor.black.cgColor
        self.layer.shadowOffset = CGSize(width: 5, height: 5)
        self.layer.shadowOpacity = 0.8
        //设置视图的内容模式为重绘
        self.contentMode = .redraw

        //pan移动
        let panGesture = UIPanGestureRecognizer(target: self, action: #selector(pan(gesture:)))
        self.addGestureRecognizer(panGesture)

        //tap删除
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(tap(gesture:)))
        self.addGestureRecognizer(tapGesture)

        //pinch缩放
        let pinchGesture = UIPinchGestureRecognizer(target: self, action: #selector(pinch(gesture:)))
        self.addGestureRecognizer(pinchGesture)

        //rotation旋转
        let rotationGesture = UIRotationGestureRecognizer(target: self, action: #selector(rotation(gestrue:)))
        self.addGestureRecognizer(rotationGesture)
    }

其中设置视图内容模式为重绘的好处是本次作业要求视图的大小和方向可以改变,当设置为重绘后,在每次改变时,他会将视图重新绘制,这样就不会出现锯齿或毛边,但这样会牺牲一些显卡和内存的资源。
在将视图设置完成之后就可以向视图添加手势了。添加手势都是用UIGestrueRecognizer的子类。用法如上,在初始化手势时,需要传入一个手势对应的方法,我们分别将对应的方法列举如下:

//pan移动
    @objc func pan(gesture: UIPanGestureRecognizer) {
        self.center = gesture.location(in: superview)
    }

    //tap删除
    @objc func tap(gesture: UITapGestureRecognizer) {
        self.removeFromSuperview()
    }

    //pinch缩放
    @objc func pinch(gesture: UIPinchGestureRecognizer) {
        let scale = gesture.scale
        self.transform = self.transform.scaledBy(x: scale, y: scale)
        gesture.scale = 1
    }

    //rotation旋转
    @objc func rotation(gestrue: UIRotationGestureRecognizer) {
        let rotation = gestrue.rotation
        self.transform = self.transform.rotated(by: rotation)
        gestrue.rotation = 0
    }

在pinch手势和rotation手势当中,我们在使用完手势获取的值之后,都需要将它初始化一次,否则的话手势的值会在之前的基础上增加,比如pinch手势,你第一次放大了2倍,第二次想再放大2倍,你所预想的结果是最后的视图的大小是原始的4倍,但如果你不初始化的话,最后的结果会是2+4=6倍。rotation手势类似。

到这里,我们自定义视图需要实现的方法就已经完成了,接下来该在控制器当中来使用我们自定义的视图了。首先为了方便管理按钮,我们将UIWindow的根视图设置为导航栏控制器(下面这句代码添加到AppDelegate.swift当中)

self.window?.rootViewController = UINavigationController(rootViewController: ViewController())

然后我们在控制器的viewDidLoad()方法中,设置根视图的标题和背景颜色,然后想导航栏上添加三个按钮

title = "Custom View"
        self.view.backgroundColor = UIColor.white

        let addBtn = UIBarButtonItem(title: "添加", style: .plain, target: self, action: #selector(addView))
        let moveBtn = UIBarButtonItem(title: "移动", style: .plain, target: self, action: #selector(moveViews))
        self.navigationItem.rightBarButtonItems = [addBtn, moveBtn]

        let clearBtn = UIBarButtonItem(title: "清空", style: .plain, target: self, action: #selector(clearView))
        self.navigationItem.leftBarButtonItem = clearBtn

我们先来实现“添加”按钮的功能,当点击这个按钮后,我们要在随机位置生成随机大小的自定义视图,所以我们需要随机生成一个点,这个点就是自定义视图的左上角的点,然后再随机生成大小值,我们就用这个点和大小来初始化一个自定义视图,并添加到根视图上即可。

@objc func addView() {
        let maxWidth: CGFloat = 150

        let x = CGFloat(arc4random() % UInt32(self.view.bounds.width))
        let y = CGFloat(arc4random() % UInt32(self.view.bounds.height - 40)) + 40
        let point = CGPoint(x: x, y: y)

        let width = CGFloat(arc4random() % UInt32(maxWidth))
        let height = CGFloat(arc4random() % UInt32(maxWidth))
        let size = CGSize(width: width, height: height)

        let view = MyView(frame: CGRect(origin: point, size: size))
        self.view.addSubview(view)
    }

(博主为了不是随机生成的自定义视图太大,所以设置了其最大宽度)

然后实现“清除”按钮,用户点击这个按钮之后,会将控制器根视图上的所有子视图全部移除。所以要用的subViews方法返回根视图的子视图的数组,然后博主使用数组的map方法来移除视图,读者如果不熟悉map方法,也可以使用循环完成。

@objc func clearView() {
        self.view.subviews.map { $0.removeFromSuperview() }
    }

最后就是随机移动视图了。在iOS 4.0之前做动画的步骤非常繁琐,但在iOS 4.0之后,Apple公司提供了一个UIView 的工厂方法来实现一些简单的动画,我们这里使用这个就可以了。

@objc func moveViews() {
        self.view.subviews.map { (view) in
            let x = CGFloat(arc4random() % UInt32(self.view.bounds.width))
            let y = CGFloat(arc4random() % UInt32(self.view.bounds.height - 40)) + 40
            let point = CGPoint(x: x, y: y)

            UIView.animate(withDuration: 3, animations: {
                view.center = point
            })
        }
    }

这个方法的使用也很简单,我们只需要先随机生成一个点,然后调用UIView 的animate(withDuration:animations:)方法就可以实现了,在这个方法中,只需要填入动画结束之后的效果即可,可以改变视图的位置、大小、方向,甚至我们可以使用一些特殊的动画,比如淡入淡出等等,读者可以自行查找相关文章阅读。(如果读者们想省事的话,可以留言博主发学习笔记给你们,如果人数太多,博主也可以写一篇相关的博文)

到这里本次的作业就完成了。
下面看看运行的效果吧:
这里写图片描述

国央企创新负责人如何通过平台实现科研成果的快速识别与转化?.docx 科易网基于AI模型+行业大数据,在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,推出科技创新领域的AI+工具与数智化解决方案,推动科技创新与产业创新智能化发展。 立即下载

相关推荐

关于爱思唯尔官方Latex模版参考文献不是按照引用顺序编号,乱序问题

接下来使用工具打开cas-model2-names.bst文件,全词匹配搜索。其他期刊的模版也是一样的操作,把规定序号的规则的。爱思唯尔给的Latex模版大概文件结构如此。发现是按照第一作者的姓氏的大写字母排序。命令行给注释掉,小写的sort可别注释。

weixin_42748439的博客 5110

GestureOverlayView(手势识别2)

GestureOverlayView:一种用于手势输入的透明覆盖层,用于识别各种手势,可以覆盖在控件上,也可以包含其他控件,有三个监听接口 1.GestureOverlayView.OnGestureListener//手势监听器 2.GestureOverlayView.OnGesturePerformed//手势执行监听器 3.GestureOverlayView.onGesturing

Ashurol的博客 746

【DeepSeek+Office/WPS】智能办公新时代的全新利器

DeepSeek是一家专注于通用人工智能技术研发的中国科技公司,其核心产品DeepSeek-R1是一款开源的推理大模型,专注于复杂任务的高效处理,支持智能对话、文本生成、语义理解、计算推理、代码生成与补全等多种应用场景。作为国产、免费、开源且强大的AI平台,DeepSeek不仅致力于为终端用户提供高质量的智能服务,还为开发者提供了一整套完善的技术解决方案,帮助他们快速构建和部署自己的智能应用。

2303_77200324的博客 2791

Android中的动画总结

Android 动画 View Animation(视图动画) 概述: 视图动画,也叫 Tween (补间)动画可以在一个视图容器内执行一系列简单变换(位置、大小、旋转、透明度)。 譬如,如果你有一个 TextView 对象,您可以移动、旋转、缩放、透明度设置其文本,当然,如果它有一个背景图像,背景图像会随着文本变化。 补间动画通过 XML 或 Android 代码定义,建议使用 XML 文件定义,因为它更具可读性、可重用性 如下是视图动画相关的类继承关系: java 类名 xml 关..

haoxuhong的博客 1389

告别抓包失败!保姆级配置:让Burp+Proxifier稳定抓取任意微信小程序

本文提供了一套完整的Burp+Proxifier配置方案,确保稳定抓取微信小程序数据。从环境准备、工具选型到Burp Suite深度配置和Proxifier精准设置,详细解决了证书安装、进程捕获和乱码解析等核心问题,帮助开发者告别抓包失败,提升调试效率。

weixin_28738165的博客 454

【抖音】a_bogus参数逆向分析

点击——展开xxx条回复﹀就会出现。可以看到这个栈是有请求相关的数据的。所以就是在bdms.js里面生成的。

qq_44990881的博客 3000

Animation Foundations: Gesture 动画基础课程之姿势 Lynda课程中文字幕

Animation Foundations: Gesture 中文字幕 动画基础课程之姿势 中文字幕Animation Foundations: Gesture 什么让一个伟大的动画角色? 一个关键部分是手势 手势是我们如何通过身体表达想法或感受; 创造自然的手势让我们的角色感到可信 指导动画师Andrew Gordon,目前在皮克斯,带领我们了解动画中的手势原理,从手部和面部手势到全身姿势 他展...

BeautifulCoding的博客 367

Verilog实战:手把手教你实现四路组相联Cache(附完整代码解析)

本文提供了一份详细的Verilog实战指南,手把手教你实现一个四路组相联Cache。内容涵盖从设计规格、核心存储阵列、LRU替换策略到状态机设计的完整流程,并附有代码解析与优化技巧,旨在帮助硬件设计者掌握Cache控制器的RTL实现与调试方法。

pp12345的博客 516

Swift4.0 Codable踩坑之派生类数据的保存

本以为之前使用Codable的过程中踩的坑已经够多了,今天博主有遇到一个坑,调了一个下午才解决,问题不大,但是中文的技术文里都很少涉及这个问题。问题描述:遵循了Codable协议的自定义类,派生出的子类JSON化与反JSON化。简单来说,就是这儿有一个类遵循了Codable协议,其自身可以很方便地使用JSONEncoder和JSONDecoder来JSON化和反JSON化。但是子类就不是那么方便了。

麻豆_matou 6659

UE5游戏逆向实战:用FModel提取.pak文件中的3D模型(附Dumper-7避坑指南)

本文详细介绍了如何使用FModel工具从UE5游戏的.pak文件中提取3D模型,并提供了Dumper-7的避坑指南。内容涵盖FModel工具链配置、UE5特有的unversioned properties问题解决方案、Dumper-7实战流程以及模型后处理技巧,帮助开发者高效获取游戏资产。

weixin_30872499的博客 422

Unity最强动作战斗框架?Combat System Framework 深度解析

Combat System Framework 并不是一个简单的角色控制器,而是一套完整的动作游戏战斗开发框架。它借鉴了现代 AAA 游戏常见的架构思想,以 Gameplay Tag 为核心,结合 ScriptableObject 数据驱动设计,将技能、属性、Buff、伤害、武器、动画通知等系统有机整合在一起。同时,配套的可视化动画时间轴、Root Motion 工具和实时预览窗口,大幅优化了动作开发流程。当然,这套框架也有一定的学习门槛。

2403_88403568的博客 680

Swift使用极光推送JPush的Demo

JPushDemo github项目地址 需要导入JPush框架,可以使用cocoapod导入,也可以手动导入 环境配置 配置环境可以参考极光推送的官方文档: iOS 证书设置指南 iOS SDK 集成指南 iOS SDK API 使用说明 待环境配置好了之后,就可以进入极光推送开始推送消息了 极光推送首页 推送使用示例如下: 发送通知 发送自定义消息 代码...

麻豆_matou 5649

Winform从入门到精通(38)——StatusStrip(史上最全)

本文介绍StatusStrip控件的详细用法,包含所有属性和事件,绝对史上最全!

qq_34059233的博客 2758

Swift从相册选择图片,图文混排并且可以保存、上传数据

博主最近突发奇想想做一个自己的日记本App,在过程中遇到了一些坑,摸索了很久才做出一个简单的日记本功能。先来看看一下效果吧: 先来说说这次用到的一些东西吧: 1、UIImagePickerController:用来获取Photos里面的照片 2、UITexeView:用来做图文混排 3、NSKeyedArchiver和NSKeyedUnarchiver:保存和读取数据 具体的一些细节在过程

麻豆_matou 4001

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

(作业)Swift类的属性与方法

话不多说,先贴作业要求 因为Person类需要一个枚举类型的gender,所以先定义枚举 //性别的枚举 enum Gender: Int { case male //男性 case female //女性 case unknow //未知 //重载>操作符,方便后面排序使用 static func >(lhs: Ge

麻豆_matou 3189

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

Swift中UIScrollView与自定义上下滑动手势冲突

今天博主在封装下拉刷新时遇到了这个问题,在给UIScrollView添加UIPanGestureRecognizer时UIScrollView无法滑动了。博主也试了UITableView和UICollectionView,也出了同样的问题。在网上找了很久,终于解决了这个问题,只需要扩展UIScrollView使它遵循UIGestureRecognizerDelegate,并实现其中的一个方法就可以

麻豆_matou 2998

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

(作业)animation、transition、UIDynamicAnimator

第二个作业要求,先来看看吧,很有趣的一些动画效果 看要求,a和b都不是很麻烦,之前博主自学的时候接触过,第三个接触不多,老师上课时演示的时候有点着迷了,因为,如果有了这个UIDynamicAnimator,那么愤怒的小鸟就不是很难实现的游戏了(有这么神么?后面再介绍吧) 关于UIDynamicAnimator,优快云的前辈写得很不错先来看看第一个用animation实现视图位置、大小、转换

麻豆_matou 2941

字符串转换为整型

在Swift中,字符串转换为整型的方法有两种,我们在这里比较一下这两种方法的区别: 1、使用强制类型转换,代码如下:var str = "1234" var integer = Int(str) print(integer) // 输出1234 但如果换一个字符串 var str = "123,4" var integer = Int(str) print(intege

麻豆_matou 2822

Swift自定义类的存储

在Swift开发中,许多时候会涉及到存储自定义的类,不管是存储到本地文件还是远程服务器,都会涉及到编码和解码的问题。下面就来介绍一下在Swift中怎么存储自定义的类。 在Swift中存储自定义的类有两种方法,一种是Swift 3.0版本的NSCoding,还有一种是Swift 4.0版本的Codable。我们就两种方法来谈谈其中的区别吧。Swift 3.0: NSCoding在NSCoding这个

麻豆_matou 2667

(作业)TableView、Delegate、DataSource

来来来,继续作业系列的博客,老规矩了,直接上要求 这次作业涉及到iOS开发中最常用的一个UI组件UITableView,App Store中的几乎所有工具型和应用型App都使用了UITableView,而初学UITableView又不是那么容易,因为它涉及到很多代理和数据源的问题,但用熟练了,会觉得它非常地方便。 废话不多说了,先来完成要求吧,在这个过程中,博主会讲解一些细节方面的东西。首先是需

麻豆_matou 2318

Swift使用XMPPFramework做IM即时通信的Demo

上一篇文章处理了文本中表情的替换,现在来完成消息的发送功能吧(貌似前后并没有逻辑关系哈) 首先为了测试,我们需要下载spark工具,它可以连接openfire搭建的后台来完成即时通信的功能,方便测试。 下载地址点这儿 博主这里用的是Spark 2.8.3,各位可以根据自己所使用的平台不同选择对应的客户端下载。由于目前只是做移动端开发,所以后台的搭建各位可以自行google。 使用S...

麻豆_matou 2288

(作业)纯代码版HelloWorld,斯坦福iOS10教学视频

这次作业不止上一篇哦,还有第二个和第三个,第三个作业是按照斯坦福老爷子的视频做一个计算器,那个很简单,博主会在文章末尾附上链接,这次主要完成第二个作业。照常,要求先上 第一个作业就用的工程里自带的视图控制器来做的,这次需要将storyboard删除并自己创建自定义的视图控制器。我们需要删除的是工程创建完成之后的Main.storyboard和ViewController.swift,然后需要更

麻豆_matou 2129

framework和cocoapod加载图片问题

最近博主应实习公司要求封装一个下拉刷新上拉加载的控件,当功能实现之后想要集成到framework中和发布到cocoapod时都遇到了图片资源读取失败的问题,现将解决办法贴下。 framework中资源读取失败: 我们需要将资源打包到.bundle文件中(其实就是后缀为.bundle的文件夹,把资源放置其中即可). 然后根据你的目录结构来获取bundle let bundle = Bundl

麻豆_matou 2041

字符串表情替换

博主最近在研究IM的实现,不想直接使用第三方的界面,于是就开始了自己的作死之路。今天把包含表情格式的文本转换成相应的富文本贴一下吧。 首先,博主的表情格式是现在常用的中括号+标志符,类似[11]就是一个表情格式的字符。 我们需要实现的功能就是把形如: 你好[11] 这样的字符串变成: 你好 这样的字符串,具体的步骤就不再叙述了,注释已经很详细了 /// 将字符串转换为含有表情的富文本 ...

麻豆_matou 1976

Swift自定义下拉刷新、上拉加载(CZXRefresh的使用)

CZXRefresh github项目地址 可以cocoapod导入 也可以下载之后手动导入 先把CZXRefresh.xcodeproj文件拖到项目下 然后配置项目文件 添加framework 使用方法 在需要使用的文件中import框架即可使用 import CZXRefresh 下拉刷新和上拉加载都可以在UITableView和UICo

麻豆_matou 1969

(作业)使用autolayout和约束实现简单的界面布局

感觉好久没有写博客了,最近博主在复习java web准备考试,顺便为后面使用UIWebKit做铺垫吧。 今天就用xcode中的stroyboard实现自动布局,我们不用写一句代码,就能实现一些基本的布局。第一套布局这儿有两套布局,我们先来看看简单的那一套。 看这套布局特别简单,只需要创建三个UIView,然后让他们总的宽度等于屏幕的宽度,然后各自的长宽相等就可以了。接下来看一步一步的操作

麻豆_matou 1852
上一篇: Swift4.0 Codable踩坑之派生类数据的保存
下一篇: (作业)ActionSheet、Alert
麻豆_matou
博客等级 码龄10年 41粉丝 46原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值