iOS 开发百问(9)
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。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。