iOS Programming Dynamic Type 2
iOS Programming Dynamic Type 2
You will need to update two parts of this view controller for Dynamic Type: the rows of your table view will grow or shrink in response to the user changing the preferred text size, and the BNRItemCell will need to be updated similarly to how you updated the BNRDetailViewController.
你的table view的row将会增大或缩小来响应用户改变preferred text size,BNRItemCell 将会知道怎样更新在BNRDetailViewController。
The goal is to have the table view row heights reflect the preferred Dynamic Type text size of the user.
目的是让table view row height 反应preferred Dynamic Type text size 。
If the user chooses a larger text size, the rows will be taller in order to accommodate the text.
如果用户选择了一个更大的text size,rows 将会变高来适应text。
Since this is not a problem that Auto Layout will solve, the row heights will need to be set manually.
因为auto layout 将解决,这不是问题,row heights将设置为手动。
To do this, you need a way of determining which text size the user has selected.
为了这样做,你需要一种方式决定哪个text size 用户想选择。
UIApplication exposes the text size that user selected through its preferredContentSizeCategory property.
UIApplication 报了出用户选择的text size 通过它的 preferredContentSizeCategory属性。
The method will return a constant NSString with the name of the content size category,
这个方法将返回一个content size category 名字的字符串。
which will be one of the following values:
(1)UIContentSizeCategoryExtraSmall
(2)UIContentSizeCategorySmall
(3)UIContentSizeCategoryMedium
(4)UIContentSizeCategoryLarge (Default)
(5)UIContentSizeCategoryExtraLarge
(6)UIContentSizeCategoryExtraExtraLarge
(7)UIContentSizeCategoryExtraExtraExtraLarge
Open BNRItemsViewController.m. Create a method that will update the table view row height based on the user-selected text size and call this method in viewWillAppear:.
[self updateTableViewForDynamicTypeSize];
Just as you did with the BNRDetailViewController earlier, you need to have the BNRItemsViewController register itself as an observer for the UIContentSizeCategoryDidChangeNotification.
像在BNRDetailViewController一样,你需要让BNRItemsViewController注册自己成为UIContentSizeCategoryDidChangeNotification的observer。
In BNRItemsViewController.m, register for the notification in init, and remove the view controller as an observer in dealloc. Finally, implement the notification call back to call the updateTableViewForDynamicTypeSize method that you just created.
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc addObserver:self
selector:@selector(updateTableViewForDynamicTypeSize) name:UIContentSizeCategoryDidChangeNotification
object:nil];
- (void)dealloc
{
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc removeObserver:self];
}
dealloc
Deallocates the memory occupied by the receiver.
释放接受者的内存
Subsequent messages to the receiver may generate an error indicating that a message was sent to a deallocated object (provided the deallocated memory hasn't been reused yet).
随后发给接受者的消息可能产生一个错误显示这个消息已经发送给了deallocated object.
You override this method to dispose of resources other than the object's instance variables,
你重写该方法除了对象的实例变量,你还dispose 资源。
for example:
- (void)dealloc {
free(myBigBlockOfMemory);
}
2.1 dealloc
In an implementation of dealloc, do not invoke the superclass's implementation.
在dealloc的实现中,不要调用超类的实现。
You should try to avoid managing the lifetime of limited resources such as file descriptors using dealloc.
你应该尽量避免管理有限资源的生命周期。
You never send a dealloc message directly. Instead, an object's dealloc method is invoked by the runtime.
你从不直接发送一个dealloc 消息。一个对象的dealloc方法会在运行时被调用。
When not using ARC, your implementation of dealloc must invoke the superclass's implementation as its last instruction.
当不适用ARC时,你实现的dealloc 必须调用它的superclass的实现作为它最后的指令。
You don't need dealloc method in ARC.
你不需要在arc中使用dealloc 。
But if you want to do some cleanup tasks when your view is dismissing or released. It's the best place, In such case you can implement it.
但是当你的view 被dismissing 或released时,你想做一些cleanup 任务。这是你最好的位置。在这种情况下,你可以实现它。
You are running a timer in your view and it's updating your view. When you are dismissed the view you need to stop that timer. In that condition you can use dealloc method and stop timer there.
你在你的view里运行了一个timer。当你dismissed 这个view,你需要停止掉timer。在这种情况下,你需要用dealloc 方法,停掉timer 在这里。
You are therefore allowed to subclass dealloc under ARC, but you are not allowed to call [super dealloc] from within the subclassed method.
当在ARC 下,不允许调用[super dealloc]
3. Updating BNRItemCell
Let's begin by implementing the Dynamic Type code to update the labels, which will closely follow what you did with BNRDetailViewController and BNRItemsViewController.
让我们开始实现Dynamic Type code 来更新labels。
Open BNRItemCell.m and make the following changes:
- (void)updateInterfaceForDynamicTypeSize
{
UIFont *font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody];
self.nameLabel.font = font;
self.serialNumberLabel.font = font;
self.valueLabel.font = font;
}
- (void)awakeFromNib
{
[self updateInterfaceForDynamicTypeSize];
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; [nc addObserver:self
selector:@selector(updateInterfaceForDynamicTypeSize) name:UIContentSizeCategoryDidChangeNotification
object:nil];
}
- (void)dealloc
{
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc removeObserver:self]; }
The only new piece of information here is the awakeFromNib method. This is called on an object after it has been unarchived from a NIB file, and is a great place to do any additional UI work that cannot be done within the XIB file.
awakeFromNib被一个对象调用在它已经从一个NIB文件中取出,这是一个合适地方做一些额外的UI工作,那些不能在XIB中文件中做的。
You can do any additional configuration for the cell that cannot be done within the XIB file within this method.
你可以做任何额外的配置为这个cell,那些不能在XIB文件中做的方法。
4 Constraint outlets
It makes sense that the image should scale with the text size. Let's do this.
让image图片和text size 一起放缩。
To update the position or size of a view, either in absolute terms or relative to another view, you should update the constraints on that view.
为了更新一个view 的位置或尺寸,不管是绝对或者与另一个view 相关,你应该更新这些view上的constraints.
In order to change the width and height of the image view, the constants on the respective constraints will need to be updated at run time.
为了改变image view 的宽和高,在各自的限制上都应该在运行时发生变化。
To do this, you will need to create an outlet to both the vertical and horizontal constraints.
为了这么做,你应该为水平和垂直限制创建outlet。
Constraints are objects (NSLayoutConstraint), so just like you can create outlets to views, the same can be done with constraints.
Constraints 是对象(NSLayoutConstraint),所以你就像创建view 的outlet一样创建constraints。
疑问:如果是Programming 编写的,怎么设置outlet呢?
In BNRItemCell.m, create and connect the outlet for these two constraints to the class extension. When you are done, the class extension should look like this:
@interface BNRItemCell ()
@property (nonatomic, weak) IBOutlet NSLayoutConstraint *imageViewHeightConstraint;
@property (nonatomic, weak) IBOutlet NSLayoutConstraint *imageViewWidthConstraint;
@end
With outlets to the size constraints of imageView created, you can now adjust imageView's size programmatically.
由于这些imageView的限制,你现在能够通过programmatically 来调整imageView的尺寸了。
In BNRItemCell.m, modify updateInterfaceForDynamicTypeSize to get the currently selected preferred text size, and use that to adjust the size of imageView.
获取当前选择的text size ,用来调整image view 的尺寸。
static NSDictionary *imageSizeDictionary;
if (!imageSizeDictionary) {
imageSizeDictionary = @{ UIContentSizeCategoryExtraSmall : @40,
UIContentSizeCategorySmall : @40, UIContentSizeCategoryMedium : @40, UIContentSizeCategoryLarge : @40, UIContentSizeCategoryExtraLarge : @45, UIContentSizeCategoryExtraExtraLarge : @55, UIContentSizeCategoryExtraExtraExtraLarge : @65 };
NSString *userSize = [[UIApplication sharedApplication] preferredContentSizeCategory];
NSNumber *imageSize = imageSizeDictionary[userSize];
self.imageViewHeightConstraint.constant = imageSize.floatValue;
self.imageViewWidthConstraint.constant = imageSize.floatValue;
4 Placeholder constraints
Instead of updating both constraints, you will add one additional constraint to imageView that will constrain the imageView's width and height to be equal.
而不是更新两个constraints,你可以给imageView添加一个constraint:constrain the imageView的宽和高相等。
You cannot create this constraint in Interface Builder, so return to BNRItemCell.m and create this constraint programmatically in awakeFromNib.
你不能在Interface Builder,所以你可以返回BNRItemCell.m,在awakeFromNib内创建这些constraint通过编程。
NSLayoutConstraint *constraint =
[NSLayoutConstraint constraintWithItem:self.thumbnailView
attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual
toItem:self.thumbnailView attribute:NSLayoutAttributeWidth
multiplier:1 constant:0];
[self.thumbnailView addConstraint:constraint];
Now, remove the imageViewWidthConstraint property and corresponding code.
There are now two constraints affecting the width of the imageView: the programmatic constraint you just created and the explicit width constraint in the XIB file.
现在你有两个限制来影响imageview的宽度。你创建的编程限制和明确指明在XIB文件的限制。
This will create unsatisfiable (conflicting) constraints if the two constraints do not agree on a size.
如果这两个限制没有达成一致,则会出现unsatisfiable constraints.
Instead, you can make the width constraint a placeholder constraint.
取而'之的是你可以制造width constraint 为一个placeholder constraint。
Placeholder constraints, as the name implies, are only temporary and are removed at build time, so they will not exist when the application is running.
placeholder constraints ,正如名字隐含的那样,仅仅是临时的,在build time 就移除了,所以当application运行是他们就不存在了。
n BNRItemCell.xib, select the width constraint on the imageView, and open the attributes inspector. Check the Placeholder box that says Remove at build time
iOS Programming Dynamic Type 2的更多相关文章
- iOS Programming Dynamic Type 1
iOS Programming Dynamic Type 1 Dynamic Type is a technology introduced in iOS 7 that helps realize ...
- 理解iOS 8中的Self Sizing Cells和Dynamic Type
http://www.cocoachina.com/ios/20140922/9717.html 在iOS 8中,苹果引入了UITableView的一项新功能--Self Sizing Cells,对 ...
- iOS Programming UIStoryboard 故事板
iOS Programming UIStoryboard In this chapter, you will use a storyboard instead. Storyboards are a f ...
- iOS Programming Web Services and UIWebView
iOS Programming Web Services and UIWebView The work is divided into two parts. The first is connecti ...
- iOS Programming UINavigationController
iOS Programming UINavigationController the Settings application has multiple related screens of info ...
- ios Programming:The Big Nerd Ranch Guid(6th Edition) (Joe Conway & AARON HILLEGASS 著)
Introduction (已看) Prerequisites What Has Changed in the Sixth Edition? Our Teaching Philosophy How t ...
- Working with the Dynamic Type in C#
Working with the Dynamic Type in C# https://www.red-gate.com/simple-talk/dotnet/c-programming/workin ...
- iOS Programming Controlling Animations 动画
iOS Programming Controlling Animations 动画 The word "animation" is derived from a Latin wor ...
- iOS Programming NSUserDefaults
iOS Programming NSUserDefaults When you start an app for the first time, it uses its factory settin ...
随机推荐
- 启动两个Tomcat的方法
由于项目需要,所以要启动两个工程,但是又不能用一个Tomcat,于是就琢磨起了怎么启动两个Tomcat 1:首先,conf/server.xml要把HTTP的端口改成不一致的,我一个是8088,一个 ...
- e3 cpu
英特尔® 至强® E3 处理器 https://www.intel.cn/content/www/cn/zh/products/processors/xeon/e3-processors.html?p ...
- C++不能在栈上申请动态内存,而只能依靠指针
以下三种情况皆错,都编译不过: int main(int argc, char* argv[]) { int a; int b[a]; } int main(int argc, char* argv[ ...
- poj2154Color polya定理+欧拉函数优化
没想到贱贱的数据居然是错的..搞得我调了一中午+晚上一小时(哦不d飞LJH掉RP毕竟他是BUFF)结果重判就对了五次.. 回归正题,这题傻子都看得出是polya定理(如果你不是傻子就看这里),还没有翻 ...
- YTU 2572: 猜灯谜
2572: 猜灯谜 时间限制: 1 Sec 内存限制: 128 MB 提交: 154 解决: 91 题目描述 A 村的元宵节灯会上有一迷题: 请猜谜 * 请猜谜 = 请边赏灯边猜 小明想,一定是每 ...
- 如何判断http服务器是否支持range寻址
如果向支持range寻址的http服务器发带range的请求 ,会有什么结果呢?是否有错误返回?数据怎么下载? 诸葛小炎fire | 浏览 569 次 您的回答被采纳后将获得: 系统奖励20(财富 ...
- Django 缓存 使用 Redis Memcached 为网站提速
RedisRedis是一种键值对类型的内存数据库,读写内存比读写硬盘快,我们在Django里面使用Redis非常方便,下面给出详细步骤 基于Ubuntu 1. 安装Redis和django-redis ...
- Linux网络协议栈(三)——网络设备(2)
2.1.网络设备的注册与注销注册网络设备发生在下列情形: (1)加载网卡驱动程序 网卡驱动程序如果被编译进内核,则它在启动时被初始化,在运行时被作为模块加载.无论初始化是否发生,所以由驱动程序控制 ...
- 关于bitset
https://www.zybuluo.com/ysner/note/1327705 原理 \(bitset\)的原理是将一大堆值为\(0/1\)的数压成一个数. 操作 通过\(i>>x\ ...
- Ueditor中代码的高亮和背景在前端页面的实现
首先废话就不多说,这个富文本编辑器的下载和js等基本文件的导入略. 我的最终目标是这样的,我们在页面中的富文本框中输入代码,希望它能够被后台接受.存入数据库,当通过服务器将这些代码再一次显示在前台的页 ...