標籤:
111、為什麼在 IB 中設定 layer.borderColor 無用?
我在 IB 中通過設定 UIView 的Runtime 屬性,以獲得一個圓角帶紅色邊框的矩形效果,如所示:
但是,borderColor 屬性似乎是無效的,邊框無法顯示。
layer.borderColor 是一個 CGColorRef 屬性,而 Runtime 屬性的顏色面板中得到的只能是 UIColor 屬性,因此你無法在 IB 中設定 borderColor,而只能通過代碼設定。
112、在 Swift 中還可以使用 DLog 宏和 ALog 宏嗎?
在C和Objective-C中使用的複雜宏無法在Swift中使用。複雜宏是除了常量定義之外的宏,包含帶括弧的函數宏。我們可以定義全域函數來代替:
func dLog(message: String, filename: String = __FILE__, function: String =__FUNCTION__, line: Int = __LINE__) {
if DEBUG==1 {
println("[\(filename.lastPathComponent):\(line)] \(function) -\(message)")
}
}
113、O-C 中的枚舉在 Swift 中無法使用?
出錯:Enum case pattern cannot match values of the non-enum type ‘枚舉名‘
截止到 Beta 5,Swift 只能映射O-C 中使用 NS_ENUM 宏定義的枚舉類。因此對於所有typedef enum 方式定義的 O-C 枚舉,都需要重新用 NS_NUM 定義:
typedef enum {
ChinaMobile = 0, // MNC 00 02 07
ChinaUnicom, // MNC 01 06
ChinaTelecom, // MNC 03 04
ChinaTietong, // MNC 20
Unknown
} CarrierName;
114、Swift 中不能使用 #ifdef 宏嗎?
Swift 中可以使用 #if/#else/#endif:
#if DEBUG
let a = 2
#else
let a = 3
#endif
但是 DEBUG 符號必須在 Other Swift Flags 中進行定義:
115、textFieldShouldReturn 方法返回 YES 或者 NO 有什麼不同?
返回 YES, 將觸發自動文本糾正和自動首字母大寫(即蘋果文檔中所謂的預設行為),返回 NO則不會。
116、如何改變 UITextView 的行高?
首先設定 UITextView 的 layouManager.delegate:
textView.layoutManager.delegate = self; // you‘ll need to declare you
然後在實現 delegate 方法:
- (CGFloat)layoutManager:(NSLayoutManager *)layoutManagerlineSpacingAfterGlyphAtIndex:(NSUInteger)glyphIndexwithProposedLineFragmentRect:(CGRect)rect
{
return 4; // 這是行間距
}
117、修改 UITextView 的最小高度
無論你如何在 IB 中修改 UITextView 的frame 高度都是無用的。UITextView的最小高度是通過它的內容來計算的,它的最小高度等於單行高度。因此在 iOS 7 上可以通過設定其 textContainerInset(iOS 6 則是 contentInset)來修改最小高度:
if (NSFoundationVersionNumber >NSFoundationVersionNumber_iOS_6_1) {
self.textContainerInset =UIEdgeInsetsMake(4, 10, 4, 10);
} else {
self.contentInset =UIEdgeInsetsMake(4, 10, 4, 10);
}
117、 在插入圖片(NSTextAttachment)後NSAttribtuedString 字型莫名被變小
插入圖片前字型:
插入圖片後:
這是因為 NSTextAttachment 插入時是以上標形式插入的,這導致三個屬性被修改:字型、baseline、 NSSuperscriptAttributeName。
因此在插入圖片後,需要將這3個值改為預設(光修改字型不行):
[mutableAttrString addAttributes:
@{NSFontAttributeName:[UIFontsystemFontOfSize:16],(id)kCTSuperscriptAttributeName:@0,NSBaselineOffsetAttributeName:@0} range:NSMakeRange(0,mutableAttrString.length)];
注意 NSSuperscriptAttributeName 在 iOS 中無效。因此需要用 CoreText 的 kCTSuperscriptAttributeName 代替。
118、如何一次性嚮導航控制器中壓入兩個 ViewController?
只需這樣:
[viewController1.navigationController pushViewController:viewController2animated:NO];
[viewController2.navigationController pushViewController:viewController3animated:YES];
第一次 PUSH 時不帶動畫,第二次 PUSH 時帶動畫,這樣使用者會覺得只 PUSH 了一個ViewController,而實際上你 PUSH 了兩個。
119、統計整個工程程式碼數
開啟終端,用cd命令 定位到工程所在的目錄,然後調用以下命名即可把每個原始碼檔案行數及總數統計出來:
find . "(" -name "*.m" -or -name "*.mm" -or-name "*.cpp" -or -name "*.h" -or -name "*.rss"")" -print | xargs wc -l
其中,-name "*.m" 就表示副檔名為.m的檔案。同時要統計java檔案和xml檔案的命令分別是:
find . "(" -name "*.java" ")" -print | xargs wc -l
find . "(" -name "*.xml" ")" -print | xargs wc -l
120、如何減少 requireGestureRecognizerToFail 方法的延時?
requireGestureRecognizerToFail一般用於區別單擊和雙擊的識別。假設你有兩個手勢,一個單擊一個雙擊,你不想在使用者雙擊時同時被識別為單擊雙擊,可以使用下列代碼:
UITapGestureRecognizer *doubleTapGestureRecognizer =[[UITapGestureRecognizer alloc]
initWithTarget:self action:@selector(handleDoubleTap:)];
doubleTapGestureRecognizer.numberOfTapsRequired = 2;
[self addGestureRecognizer:doubleTapGestureRecognizer];
UITapGestureRecognizer *singleTapGestureRecognizer =[[UITapGestureRecognizer alloc] initWithTarget:selfaction:@selector(handleSingleTap:)];
singleTapGestureRecognizer.numberOfTapsRequired = 1;
[singleTapGestureRecognizer requireGestureRecognizerToFail: doubleTapGestureRecognizer];
[selfaddGestureRecognizer:singleTapGestureRecognizer];
但是這個方法有個致命的缺點,由於每次單擊都要先進行雙擊的識別,而且要等雙擊識別失敗才進行單擊的處理,導致每次單擊都會有一個延遲,一般這個時間會是 0.35 秒。儘管 0.35 秒很短,但使用者能感到明顯的延遲。因此我們需要重載 TapGestureRecognizer,減少這個延時:
#import <UIKit/UIGestureRecognizerSubclass.h>
#define UISHORT_TAP_MAX_DELAY 0.25
@interface UIShortTapGestureRecognizer : UITapGestureRecognizer
@property(nonatomic,assign)float maxDelay;
@end
#import"UIShortTapGestureRecognizer.h"
@implementation UIShortTapGestureRecognizer
- (instancetype)initWithTarget:(NSObject*)target action:(SEL)selector{
self=[super initWithTarget:targetaction:selector];
if (self) {
self.maxDelay=UISHORT_TAP_MAX_DELAY;
}
return self;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesBegan:toucheswithEvent:event];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW,(int64_t)(self.maxDelay * NSEC_PER_SEC)), dispatch_get_main_queue(), ^
{
// 0.1 秒後,宣告手勢識別失敗
if (self.state !=UIGestureRecognizerStateRecognized)
{
self.state= UIGestureRecognizerStateFailed;
}
});
}
@end
現在可以在執行個體化 UIShortTapGestureRecognizer 之後設定它的 maxDelay屬性了。注意,這個值不要小於 0.2秒(使用者必須非常快,否則無法完成雙擊動作),最佳為 0.25。
iOS 開發百問(9)