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。


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