首頁  >  文章  >  後端開發  >  iOS 開發百問(9)

iOS 開發百問(9)

黄舟
黄舟原創
2017-01-20 09:50:111277瀏覽

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則不會。
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; // 这是行间距
}

在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 
#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)的內容,更多相關內容請關注PHP中文網(www.php.cn)!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn