当用户摇动设备时,UIKit将评估加速度计数据,以确定它是否符合摇动手势。如果是这样,当摇晃开始和停止时,UIKit将活动事件传送到活动应用的第一响应者。您可以使用动作事件触发您的应用程序中的行为。
API 查看
实现摇一摇功能主要是通过 UIResponder 类 的运动事件来实现的,运动事件主要有三个方法:
// 开始运动
@available(iOS 3.0, *)
open func motionBegan(_ motion: UIEventSubtype, with event: UIEvent?)
// 取消运动
@available(iOS 3.0, *)
open func motionEnded(_ motion: UIEventSubtype, with event: UIEvent?)
// 运动结束
@available(iOS 3.0, *)
open func motionCancelled(_ motion: UIEventSubtype, with event: UIEvent?)
复制代码
UIKit 通过调用motionBegan:withEvent:和motionEnded:withEvent: 两个方法来报摇动手势的开始和结束。(UIKit在 shake 时不通知您的响应者。) 我们可以根据需求实现这些方法中的一个或两个来执行任何相关任务。 我们还可以执行motionCancelled:withEvent:方法来处理UIKit取消摇动手势的情况。如果摇动动作中断或者如果确定当前动作不构成有效的摇动手势,则UIKit将取消摇动手势 - 例如,如果抖动持续时间太长的情况。
功能实现
我们试着实现微信的摇一摇功能。主要代码如下:
//
// ViewController.swift
// ShakeDevice
//
// Created by YHY on 2017/3/29.
// Copyright © 2017年 太阳在线. All rights reserved.
//
import UIKit
import SnapKit
class ViewController: UIViewController {
var topView: UIView! // 摇动分开始的上部分 View
var bottomView: UIView! // 下部分 View
var topImageView: UIImageView! // 上部分 imageView
var bottomImageView: UIImageView! // 下部分 imageView
override func viewDidLoad() {
super.viewDidLoad()
// 使用 Snapkit 布局
topView = UIView()
topView.backgroundColor = UIColor.white
view.addSubview(topView)
topView.snp.makeConstraints { (make) in
make.top.leading.trailing.equalToSuperview()
make.height.equalToSuperview().multipliedBy(0.5)
}
bottomView = UIView()
bottomView.backgroundColor = UIColor.white
view.addSubview(bottomView)
bottomView.snp.makeConstraints { (make) in
make.bottom.leading.trailing.equalToSuperview()
make.height.equalToSuperview().multipliedBy(0.5)
}
topImageView = UIImageView()
topImageView.image = UIImage(named: "摇一摇1")
// topImageView.contentMode = .bottom
topView.addSubview(topImageView)
topImageView.snp.makeConstraints { (make) in
make.bottom.equalToSuperview()
make.centerX.equalToSuperview()
make.width.equalTo(66)
make.height.equalTo(33)
}
bottomImageView = UIImageView()
bottomImageView.image = UIImage(named: "摇一摇2")
//bottomImageView.contentMode = .top
bottomView.addSubview(bottomImageView)
bottomImageView.snp.makeConstraints { (make) in
make.top.equalToSuperview()
make.centerX.equalToSuperview()
make.width.equalTo(66)
make.height.equalTo(33)
}
// 添加一个监测 shake 的通知,当摇动结束的时候,发出通知,就可以实现我们想实现的功能了。示例中打印了“摇一摇”三个字
// 注意: 其实本示例中,通知部分可以去掉,因为不使用通知,类似于微信摇一摇功能也已经实现了,写在这里只是提供,一种处理方式
NotificationCenter.default.addObserver(self, selector: #selector(shake), name: NSNotification.Name(rawValue: "shake"), object: nil)
}
func shake() {
print("摇一摇")
}
// 开始摇动,添加你的需求代码
override func motionBegan(_ motion: UIEventSubtype, with event: UIEvent?) {
// 这里判断了一下 motion 的值,可以点进去看一下 motion 都有哪些值。个人认为其实不判断也没关系
if motion == .motionShake
{
// 使用 SnapKit 实现摇一摇开始的动画,图片分开,其实这里还可以加上声音,本示例未实现
UIView.animate(withDuration: 1.5) {
self.topView.snp.remakeConstraints { (make) in
make.leading.trailing.equalToSuperview()
make.top.equalToSuperview().offset(-66)
make.height.equalToSuperview().multipliedBy(0.5)
}
self.bottomView.snp.remakeConstraints { (make) in
make.leading.trailing.equalToSuperview()
make.bottom.equalToSuperview().offset(66)
make.height.equalToSuperview().multipliedBy(0.5)
}
self.view.layoutSubviews()
}
}
}
// 取消摇动
override func motionCancelled(_ motion: UIEventSubtype, with event: UIEvent?) {
// 摇一摇的时候会出现,两张图分开之后停住无法合在一起的状况,这里必须处理一下
endShake()
}
// 摇动结束
override func motionEnded(_ motion: UIEventSubtype, with event: UIEvent?) {
// 这里睡眠一秒,其实可以不加,只是为了视觉上舒服
sleep(1)
endShake()
// 发出通知,其实本示例中,通知部分可以去掉,因为不使用通知,类似于微信摇一摇功能也已经实现了
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "shake"), object: self)
}
func endShake() {
// 使用 SnapKit 实现摇一摇结束的动画,图片合上
UIView.animate(withDuration: 1.5) {
self.topView.snp.remakeConstraints { (make) in
make.top.leading.trailing.equalToSuperview()
make.height.equalToSuperview().multipliedBy(0.5)
}
self.bottomView.snp.remakeConstraints { (make) in
make.bottom.leading.trailing.equalToSuperview()
make.height.equalToSuperview().multipliedBy(0.5)
}
self.view.layoutSubviews()
}
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
// 移除通知
NotificationCenter.default.removeObserver(self)
}
}
复制代码
默认大家都会使用 SnapKit ,不会使用的话我这里有。
效果实例图:
Demo下载 。