iOS Programming Views :Redrawing and UIScrollView,iosuiscrollview
iOS Programming Views :Redrawing and UIScrollView
1.1 event
You are going to see how views are redrawn in response to an event.
你將看到view如何響應event的。
You declared properties in header files. You can also declare properties in class extensions.
你可以聲明屬性在header檔案,也可以聲明在class extensions中。
#import "BNRHypnosisView.h"
@interface BNRHypnosisView ()
@property (strong, nonatomic) UIColor *circleColor;
@end
@implementation BNRHypnosisView
These three lines of code are a class extension with one property declaration.
有三行代碼在一個類擴充中。
When the user touches a view, the view is sent the message touchesBegan:withEvent:.
當使用者觸摸一個view 時,這個view將會發送訊息給tochesBegan:withEvent:
Override touchesBegan:withEvent: to change the circleColor property of the view to a random color.
重寫touchesBegan:withEvent方法
// When a finger touches the screen
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(@"%@ was touched", self);
// Get 3 random numbers between 0 and 1 float red = (arc4random() % 100) / 100.0; float green = (arc4random() % 100) / 100.0; float blue = (arc4random() % 100) / 100.0;
UIColor *randomColor = [UIColor colorWithRed:red green:green
blue:blue alpha:1.0];
self.circleColor = randomColor; }
1.2 Run Loop and redrawing views 迴圈和重繪views
When an iOS application is launched, it starts a run loop. The run loop's job is to listen for events, such as a touch.
當一個iOS application啟動後,它便開始迴圈了。run loop's工作就是監聽事件,如touch
When an event occurs, the run loop then finds the appropriate handler methods for the event. Those handler methods call other methods, which call more methods, and so on. Once all of the methods have completed, control returns to the run loop.
當event發生後,run loop 要找到合適的handler 方法處理event。這個handler 處理其他方法,調用更多的方法。直到所有的方法完成後,控制權又回到了run loop。
When the run loop regains control, it checks a list of "dirty views" – views that need to be re- rendered based on what happened in the most recent round of event handling.
當run loop重新得到控制權後,它會檢測一系列的dirty views- views 根據最近的event handling 發生了什麼要重繪 。
The run loop then sends the drawRect: message to the views in this list before all of the views in the hierarchy are composited together again.
在所有的view重新組合以前,run loop 會發送資訊給在列表中得view 的drawRect方法。
Batching the redrawing of views at the end of a run loop cycle prevents needlessly redrawing a view more than once if more than one of its properties is changed in a single event.
批量處理redrawing of views 在run loop 的結尾,可以節約大量的時間。
To get a view on the list of dirty views, you must send it the message setNeedsDisplay.
為了讓一個views加入dirty views 的列表中,你應該向該view發送setNeedsDisplay.
The subclasses of UIView that are part of the iOS SDK send themselves setNeedsDisplay whenever their content changes.
在iOS SDK內的UIView子類都會給自己發送setNeedsDisplay,無論什麼時候他們的內容改變。
In custom UIView subclasses, like BNRHypnosisView, you must send this message yourself.
In BNRHypnosisView.m, implement a custom accessor for the circleColor property to send setNeedsDisplay to the view whenever this property is changed.
在我們的例子中,我們在accessor 的set方法中設定setNeedsDisplay。
- (void)setCircleColor:(UIColor *)circleColor
{
_circleColor = circleColor;
[self setNeedsDisplay]; }
1.3 Class Extensions
What is the difference between a property declared in a class extension and one declared in a header file?
聲明在class extension and in header file?
A class's header file is visible to other classes. That, in fact, is its purpose. A class declares properties and methods in its header file to advertise to other classes how they can interact with the class or its instances.
在header file中聲明的變數可以被別的類調用。這也是其目的。
Properties and methods that are used internally by the class belong in a class extension.
屬性或方法只用在內部的就可以在類擴充中調用。
It is good practice to keep your header file as brief as it can be. This makes it easier for others to understand how they can use your class.
讓header file 保持小得尺寸是個好習慣。能讓別人更容易理解你得類。
a class extension looks a little like a header file. It begins with @interface followed by an empty set of parentheses. The @end marks the end of the class extension.
一個類擴充@interface開頭,緊跟著是類名,後面是個空括弧。
2.1 UIScrollView
Scroll views are typically used for views that are larger than the screen. A scroll view draws a rectangular portion of its subview, and moving your finger, or panning, on the scroll view changes the position of that rectangle on the subview.
Scroll views 用作那些比螢幕大的view 。 一個scroll view 畫它的subview 的一部分。當你在scroll view 上移動手指時將改變矩形在subview 上的位置。
Thus, you can think of the scroll view as a viewing port that you can move around
因此可以把scroll view 看做是一個view port。
The size of the scroll view is the size of this viewing port.
scroll view 的尺寸是你看到的視圖部分。
The size of the area that it can be used to view is the UIScrollView's contentSize, which is typically the size of the UIScrollView's subview.
而你能用到view的尺寸是UIScrollView的contentSize,也就是UIScrollView的subview的尺寸。
// Create CGRects for frames
CGRect screenRect = self.window.bounds; CGRect bigRect = screenRect; bigRect.size.width *= 2.0; bigRect.size.height *= 2.0;
// Create a screen-sized scroll view and add it to the window
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:screenRect];
[self.window addSubview:scrollView];
// Create a super-sized hypnosis view and add it to the scroll view
BNRHypnosisView *hypnosisView = [[BNRHypnosisView alloc] initWithFrame:bigRect];
[scrollView addSubview:hypnosisView];
// Tell the scroll view how big its content area is scrollView.contentSize = bigRect.size;
2.2 Panning and paging
Another use for a scroll view is panning between a number of view instances.
另外scroll view的一個應用是panning (應該是切換的意思) view instances 。
// Create a screen-sized hypnosis view and add it to the scroll view BNRHypnosisView *hypnosisView = [[BNRHypnosisView alloc] initWithFrame:screenRect];
To force the scroll view to snap its viewing port to one of the views, turn on paging for the scroll view in BNRAppDelegate.m.
有時候你不想讓圖停在中間位置,你可以用pagingEnabled =yes;
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:screenRect]; scrollView.pagingEnabled = YES;
[self.window addSubview:scrollView];
Paging works by taking the size of the scroll view's bounds and dividing up the contentSize it displays into sections of the same size.
分頁通過獲得scroll view的bounds並且劃分 contentsize,顯示成相同尺寸的分節。
After the user pans, the view port will scroll to show only one of these sections.
在使用者來回翻的時候,視圖連接埠就只顯示這些分節中的一個。