iOS应用开发视频教程笔记(十六)Action Sheets, Image Picker, Core Motion

本文主要是介绍iOS应用开发视频教程笔记(十六)Action Sheets, Image Picker, Core Motion,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

这节课主要讲NSTimer的内容以及它的替代方案“perform after delay”、更复杂的动画、Alerts、Action Sheets、UIImagePickerController(用来从camera里取东西)和Core Motion。

NSTimer

先调用这个工厂方法scheduledTimerWithTimeInterval,如果它是一个重复timer,停止timer的方法是:

- (void)invalidate;

如果不是一个重复timer,不需要invalidate,它自己会结束。可以看到repeats是YES或NO,代表是否重复。如果有一个strong指针指向它,那么需要将其设置为nil;如果是一个weak指针,它自己就可能把自己nil掉。所以这是除了outlet之外,另一种可能会使用一个弱指针的情况。调用了scheduledTimerWithTimeInterval,在它运行的时候会有强指针指向它,一旦通过invalidate停止它,它就不会再有强指针。

Perform after Delay

这是个NSObject的实例方法,它让一个对象执行这个参数为withObject的selector,也可以没有参数,这种情况下withObject将是nil。在一定的afterDelay之后执行:

- (void)performSelector:(SEL)aSelectorwithObject:(id)argument afterDelay:(NSTimeInterval)seconds;

它利用当前线程的run loop机制执行。不是每个线程都有一个run loop,主线程肯定有run loop,该run loop要处理很多东西。不是任意线程都可以执行Perform after Delay的,在本课程内只能在主线程执行。

这不是实时的,和NSTimer一样,如果说延迟0.72秒后执行,run loop可能在忙,这种情况下它实际上直到0.74秒后才执行。它只是放到了run loop里,直到run loop空闲了并超过了该delay时间,它才会运行。有一点要注意,它永远不会立即执行。离开屏幕的时候要确保它停止了。

[self.tableView performSelector:@selector(reloadData) withObject:nil afterDelay:0];

如何取消?在做了Perform after Delay之后,你在它完成前意识到“不想它发生”,需要调用这个类方法:

+ (void)cancelPreviousPerformRequestsWithTarget:(id)targetselector:(SEL)aSelector object:(id)object; 
+ (void)cancelPreviousPerformRequestsWithTarget:(id)target;

你指定消息、发起的对象、selector和参数,系统会去取消它。下面一个方法将取消该目标的所有执行要求。

没有办法找出它们来,没有办法查询正在排队的执行事件。

Alerts and Action Sheets

有两种方式来提醒用户:有一个叫action sheet,它从iphone的底部弹出或者在ipad的popover弹出,它提供了一个选项让用户决定下一步做什么;还有另一种提醒,叫做UIAlert,它更多用于异步发生的事情。


UIActionSheet

这是它的指定初始化方法:

    -(id)initWithTitle:(NSString *)title delegate:(id <UIActionSheetDelegate>)delegatecancelButtonTitle:(NSString *)cancelButtonTitle 
destructiveButtonTitle:(NSString *)destructiveButtonTitleotherButtonTitles:(NSString *)otherButtonTitles, ...;

title出现在action sheet的顶部,用delegate来指导用户的选择,一个取消按钮的标题,通常就是cancel,最后是其他按钮的标题,想要几个就几个,以nil结尾。通常在初始化时就指定好所有的按钮,但也可以用addButtonWithTitle动态添加:

- (void)addButtonWithTitle:(NSString *)buttonTitle;

创建之后,可以用以下显示方法中的一个来显示它:

UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:...];
[actionSheet showInView:(UIView*)]; //centerstheviewoniPad(don’tusethisoniPad) 
[actionSheet showFromRect:(CGRect) inView:(UIView *) animated:(BOOL)];    // good on iPad 
[actionSheet showFromBarButtonItem:(UIBarButtonItem *) animated:(BOOL)]; // good on iPad

showInView是显示在iphone的中间位置,它会从下往上滑动;在ipad上它会放在中间,所以在ipad上从不用showInView。showFromRect,在ipad上指定个矩形区域,它会在其上显示个popover。showFromBarButtonItem,就是popover会指向个BarButtonItem。在iphone上只能使用showInView,如果是universal app,要用些if来判断。

用delegate来知道用户选择了什么:

- (void)actionSheet:(UIActionSheet *)sender clickedButtonAtIndex:(NSInteger)index;

这里的index用来和action sheet里的一些property对照,如cancel button或destructive button或title:

@property NSInteger cancelButtonIndex;      // don’t set this if you set it in initializer 
@property NSInteger destructiveButtonIndex; // don’t set this if you set it in initializer

还可以知道第一个按钮的index是什么,然后可以做一些计算的东西,通常情况下,只需要比较字符串。

也可以用代码来关闭action sheet,最常见和最重要的原因之一是,app被退到后台了:

- (void)dismissWithClickedButtonIndex:(NSInteger)index animated:(BOOL)animated;

如何知道即将进入后台?只要监听UIApplicationDidEnterBackgroundNotification,popover要多考虑几件事:

一,它没有取消按钮;

二,当popover action sheet来自UIBarButton,该toolbar会被添加到popover的passthroughViews,passthroughViews就是点击之后该popover不会消失,这意味着如果有bar button,它们还会响应;

三,必须确保如果bar button被再次按下,不会出现第二个action sheet。

UIAlertView

它的初始化几乎和action sheet一样:

-(id)initWithTitle:(NSString *)title message:(NSString *)message // different from UIActionSheetdelegate:(id <UIActionSheetDelegate>)delegate cancelButtonTitle:(NSString *)cancelButtonTitle otherButtonTitles:(NSString *)otherButtonTitles, ...;

它有个message,比如网络连接失败之类的。此外,没有destructive button。仍然可以添加更多button,用show来显示:

- (void)addButtonWithTitle:(NSString *)buttonTitle;
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:...]; 
[alertView show];    // different from UIActionSheet, always appears in center of screen

UIImagePickerController

这是你要如何从相机获得图像。这只是一个view controller,和其他的controller使用方法一样。在iPad上,可以modally显示它,会覆盖整个屏幕或者可以放到popover上。

怎么实现呢?用alloc/init来创建它,然后配置它,配置主要是说你想要什么,比如视频、图片或查找photo library、还是要拍照等等,然后使用两个方法来显示出来,最后你响应这个会告诉你用户选了什么的delegate方法。

用户可以做什么很大程度上取决于他们的设备,通过它的类方法isSourceTypeAvailable来知道哪些是可用的:

+ (BOOL)isSourceTypeAvailable:(UIImagePickerControllerSourceType)sourceType;

共有三种不同的source type:UIImagePickerControllerSourceTypePhotoLibrary/Camera/SavedPhotosAlbum。

即使设备有摄像头,它也可能无法录视频,所以必须做第二次检查:

+ (NSArray *)availableMediaTypesForSourceType:(UIImagePickerControllerSourceType)sourceType;

如果设备支持你选的source type,比如camera,然后你问它是否支持你要的media type,比如该camera是否能录视频。

只有两种有用的source type:一个是image,一个是movie。必须import <MobileCoreServices/MobileCoreServices.h>,而且必须添加整个MobileCoreServices framework,否则无法使用kUTTypeImage和kUTTypeMovie这两个常量。kUTTypeImage和kUTTypeMovie不是NSString,而是CFString,所以你要做强制转换。

下面是个例子,如何设置source type和media type:

复制代码
复制代码
UIIPC *picker = [[UIIPC alloc] init]; 
picker.delegate=self; //self has to say it implements UINavigationControllerDelegate too:( 
if ([UIIPC isSourceTypeAvailable:UIIPCSourceTypeCamera]) {picker.sourceType = UIIPCSourceTypeCamera; 
} // else we’ll take what we can get (photo library by default)
NSString*desired=(NSString*)kUTTypeMovie; //e.g.,couldbekUTTypeImage
if ([[UIIPC availableMediaTypesForSourceType:picker.sourceType] containsObject:desired]) {picker.mediaTypes = [NSArray arrayWithObject:desired];// proceed to put the picker up
}else {// fail, we can’t get the type of media we want from the source we want
}
复制代码
复制代码

你在配置这个picker,来让用户选东西,如果用了camera或photo library,可以让用户有一个界面进行编辑,放大它、移动并截取部分等等。

@property BOOL allowsEditing;

可以限制视频的数据量:

@property UIIPCQualityType videoQuality;

在用户选好照片,编辑完之后,此delegate方法将被调用:

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{// extract image/movie data/metadata here, more on the next slide [self dismissModalViewControllerAnimated:YES]; // or popover dismissal
}

它有个很重要的参数info,我们要的所有信息都在info里。这里要注意的是,如果这是一个modalViewController,需要dismiss它。

它发了个cancel消息,必须关闭它:

- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{[self dismissModalViewControllerAnimated:YES]; // or popover dismissal
}

info是个dictionary,左边是key,右边是value type。

复制代码
复制代码
UIImagePickerControllerMediaType          // kUTTypeImage or kUTTypeMovie
UIImagePickerControllerOriginalImage      // UIImage
UIImagePickerControllerEditedImage        // UIImage
UIImagePickerControllerCropRect           // CGRect (in an NSValue)
UIImagePickerControllerMediaMetadata      // NSDictionary info about the image to save later
UIImagePickerControllerMediaURL           // NSURL edited video
UIImagePickerControllerReferenceURL       // NSURL original (unedited) video
复制代码
复制代码

有一整套可以在camera上叠加东西的机制,可以实时地把自己的UI叠加到相机上,也可以有自己的照相按钮。

Core Motion

Core Motion是一个用来访问重力感应硬件的API集合,有加速度计、陀螺仪、磁力计。Accelerometer告诉你设备在3个空间维度里的加速度,Gyro告诉你设备的旋转,Magnetometer告诉你很多关于设备在位置方面的信息,特别是设备几秒前或几毫秒前的位置。

和之前的相机一样,要先了解设备能做什么,通过一个CMMotionManager类来访问motion信息,它有个类方法shared motion manager,通过这个方法来获得motion manager。

要怎么用motion manager?要先检查看看有什么样的硬件可用,然后简单地轮询它来获取数据,或更好一些:把一个block放到一个queue上,以你需要的速率反馈回来最新的数据。有两种方式,询问或调用block。

怎么检查传感器的可用性?CMMotionManager有这些property:

@property (readonly) BOOL {accelerometer,gyro,magnetometer,deviceMotion}Available;

然后就可以用start update开始启动硬件了:

- (void)start{Accelerometer,Gyro,Magnetometer,DeviceMotion}Updates;

还可以知道CMMotionManager当前是否在从特定的硬件收集数据:

@property (readonly) BOOL {accelerometer,gyro,magnetometer,deviceMotion}Active;

当你用完了,要停止它,事实上得尽可能少用这个东西,因为开销很大,不用的时候别让它在后台运行:

- (void)stop{Accelerometer,Gyro,Magnetometer,DeviceMotion}Updates;

CMDeviceMotion会分别告诉你加速度和重力加速度,它会帮你排除所有的设备错误。


这篇关于iOS应用开发视频教程笔记(十六)Action Sheets, Image Picker, Core Motion的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/834550

相关文章

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

中文分词jieba库的使用与实景应用(一)

知识星球:https://articles.zsxq.com/id_fxvgc803qmr2.html 目录 一.定义: 精确模式(默认模式): 全模式: 搜索引擎模式: paddle 模式(基于深度学习的分词模式): 二 自定义词典 三.文本解析   调整词出现的频率 四. 关键词提取 A. 基于TF-IDF算法的关键词提取 B. 基于TextRank算法的关键词提取

水位雨量在线监测系统概述及应用介绍

在当今社会,随着科技的飞速发展,各种智能监测系统已成为保障公共安全、促进资源管理和环境保护的重要工具。其中,水位雨量在线监测系统作为自然灾害预警、水资源管理及水利工程运行的关键技术,其重要性不言而喻。 一、水位雨量在线监测系统的基本原理 水位雨量在线监测系统主要由数据采集单元、数据传输网络、数据处理中心及用户终端四大部分构成,形成了一个完整的闭环系统。 数据采集单元:这是系统的“眼睛”,

Hadoop企业开发案例调优场景

需求 (1)需求:从1G数据中,统计每个单词出现次数。服务器3台,每台配置4G内存,4核CPU,4线程。 (2)需求分析: 1G / 128m = 8个MapTask;1个ReduceTask;1个mrAppMaster 平均每个节点运行10个 / 3台 ≈ 3个任务(4    3    3) HDFS参数调优 (1)修改:hadoop-env.sh export HDFS_NAMENOD

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

hdu1394(线段树点更新的应用)

题意:求一个序列经过一定的操作得到的序列的最小逆序数 这题会用到逆序数的一个性质,在0到n-1这些数字组成的乱序排列,将第一个数字A移到最后一位,得到的逆序数为res-a+(n-a-1) 知道上面的知识点后,可以用暴力来解 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#in

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

OpenHarmony鸿蒙开发( Beta5.0)无感配网详解

1、简介 无感配网是指在设备联网过程中无需输入热点相关账号信息,即可快速实现设备配网,是一种兼顾高效性、可靠性和安全性的配网方式。 2、配网原理 2.1 通信原理 手机和智能设备之间的信息传递,利用特有的NAN协议实现。利用手机和智能设备之间的WiFi 感知订阅、发布能力,实现了数字管家应用和设备之间的发现。在完成设备间的认证和响应后,即可发送相关配网数据。同时还支持与常规Sof

zoj3820(树的直径的应用)

题意:在一颗树上找两个点,使得所有点到选择与其更近的一个点的距离的最大值最小。 思路:如果是选择一个点的话,那么点就是直径的中点。现在考虑两个点的情况,先求树的直径,再把直径最中间的边去掉,再求剩下的两个子树中直径的中点。 代码如下: #include <stdio.h>#include <string.h>#include <algorithm>#include <map>#

活用c4d官方开发文档查询代码

当你问AI助手比如豆包,如何用python禁止掉xpresso标签时候,它会提示到 这时候要用到两个东西。https://developers.maxon.net/论坛搜索和开发文档 比如这里我就在官方找到正确的id描述 然后我就把参数标签换过来