欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  后端开发

iOS 开发百问(9)

程序员文章站 2022-05-29 21:09:13
...
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)的内容,更多相关内容请关注PHP中文网(www.php.cn)!

相关标签: iOS,开发百问