iOS开发中,屏幕适配也是项很重要的工作,本文记录了一些在屏幕适配的过程中与图片相关的工作。

基本概念

首先,理解几个概念: Points, Rendered Pixels, Physical Pixels, Physical Device。

  • Points: 是iOS开发中引入的抽象单位,称作点。开发过程中所有基于坐标系的绘制都是以 point 作为单位,在iPhone 2G,3G,3GS的年代,point 和屏幕上的像素是完全一一对应的,即 320 * 480 (points), 也是 320 * 480 (pixels)
  • Rendered Pixels: 渲染像素, 以 point 为单位的绘制最终都会渲染成 pixels,这个过程被称为光栅化。基于 point 的坐标系乘以比例因子可以得到基于像素的坐标系,高比例因子会使更多的细节展示,目前的比例因子会是 1x,2x,3x
  • Physical Pixels: 物理像素,就是设备屏幕实际的像素
  • Physical Device: 设备屏幕的物理长度,使用英寸作为单位。比如iPhone 4屏幕是3.5英寸,iPhone 5 是4英寸,iphone 6是4.7英寸,这里的数字是指手机屏幕对角线的物理长度。实际上会是Physical Pixels的像素值(而不是Rendered Pixels的像素值)会渲染到该屏幕上, 屏幕会有 PPI(pixels-per-inch) 的特性,PPI 的值告诉你每英寸会有多少像素渲染。
Continue reading

本文记录如何在 UIStoryboard 或者 xib 中进行百分比布局,包括

  • View.Width 占其 Superview.Width 的百分比
  • View.Leading 与 Superview.Leading 间距占 Superview.Width 的百分比
  • View.Trailing 与 Superview.Trailing 间距占 Superview.Width 的百分比
  • View.Leading 与 Superview.CenterX 间距占父视图 Superview.Width 的百分比
  • 限定View的宽高比
  • 以 Superview.Width 宽度的某一百分比为 View 之间的间隔
Continue reading

进一步阅读之前,可以先思考这个问题: 存在数组 @[@(90), @(31), @(65), @(78), @(76)],如何取出数组中的最大值或者最小值?

KVC 的集合操作符可使用键路径和操作运算作用于集合中的所有元素。本文将描述一些可用的集合操作。

KVC 的集合操作符实际上就是一些特殊的键路径,以参数的形式传递给 valueForKeyPath: 方法。集合操作是以 @* 开始的字符串, 也可理解为: KVC集合操作符允许在 valueForKeyPath: 方法中使用 key path 符号在一个集合中执行方法。无论什么时候你在 key path 中看见了@*,它都代表了一个特定的集合方法,其结果可以被返回或者链接,就像其他的 key path 一样。下图就是集合操作符的格式:

Operator key path format
Operator key path format

其中左边的键路径(keypathToCollection)指定了相对消息接收者的 NSArray 或者 NSSet,右边的键路径(keypathToProperty)指定了相对于集合内对象的键路径,集合操作作用于该键路径。

Continue reading

KVO, 即键值观察,提供了一种让一个对象监听另一个对象的特定属性变化的机制。这在 MVC 的 Model 层 和 Controller 层间通信十分有用。通常情况下,Controller 会监听 Model 对象的属性变化,或者 View 对象会通过 Controller 来监听 Model 对象的属性变化。除此之外,在 Model 对象需要感知其依赖值的改变的时候,该 Model 对象也可以监听其他 Model 对象或者其自身的属性变化。

监听属性变化需要以下几步:

  1. 使用函数 addObserver:forKeyPath:options:context: 建立观察者和被观察者对象之间的连接,这种连接不是建立在这两个类之间,而是两个对象实例之间。
  2. 为了响应被观察者对象的变化通知,观察者必须实现 observeValueForKeyPath:ofObject:change:context: 方法,该方法定义了观察者是如何对被观察者的变化做出响应的。
  3. 当被观察的属性发生变化时,observeValueForKeyPath:ofObject:change:context: 方法会自动调用。
  4. 调用 – removeObserver:forKeyPath:context: 取消注册。
Continue reading

在项目,可能会有需求需要监听 NSMutableArray 的变化,例如在可变数组中加入、删除或者替换了元素,我们需要根据这些变化来更新UI或者做其他操作。

那么如何来监听呢?

方法1,使用 mutableArrayValueForKey: 代理,这样,我们在获取定义的数组属性时不再使用其 getter 方法,而是通过代理方法获取数组属性后,再对数组进行增删改的操作。这是最简单高效的方法,使用示例如下:

Continue reading

使用 Storyboard 时,通常情况下,可能你不会去关心 NSLayoutConstraint 的 priority 属性,使用 Storyboard 提供的默认值就能达到要求。但是最近遇到对 UILabel 的如下布局要求时,就需要涉及对 priority 的修改。

NSLayoutConstraint priority 示例
NSLayoutConstraint priority 示例

如上所示,我们期望 UILabel 显示字符串较短时,以内容的多少来决定其宽度;当其显示的字符串较长时,截断其尾部,且 UILabel 的 Trailing 距离 UIButton 的 Leading 大于等于30,UIButton的宽度由其title内容决定。在 Storyboard 将 UILabel 和 UIButton 设置好约束,不改变约束的 priority 的前提下,在 Xcode6.4 的环境下会出现约束错误提示。你可先考虑为什么会出现约束错误以及如何解决这种错误。

Continue reading

iOS 中可获取当前网络接口的 SSIDBSSID 信息,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
NSString *ssid = @"";
NSString *bssid = @"";
NSArray *ifs = (__bridge_transfer id)CNCopySupportedInterfaces();
NSDictionary *info;
if ([ifs count] > 0) {
for (NSString *ifname in ifs) {
info = (__bridge_transfer id)CNCopyCurrentNetworkInfo((__bridge CFStringRef)ifname);

NSString *ssidKey = (__bridge_transfer NSString *)kCNNetworkInfoKeySSID;
NSString *bssidKey = (__bridge_transfer NSString *)kCNNetworkInfoKeyBSSID;
if (info) {
ssid = info[ssidKey];
bssid = info[bssidKey];
NSLog(@"ssid: %@", ssid);
NSLog(@"bssid: %@", bssid);
}
}
}
Continue reading
Author's picture

CaryaLiu

@Chengdu


iOS Developer


Chengdu