iOS 根据字符串计算label高度

直接上代码

tipLabel = [[UILabel alloc] init];
    [self.backScrollView addSubview:tipLabel];
    NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];
    [style setLineSpacing:10];
    NSString *tipStr = @"温馨提示:这是要计算高度的字符串";
    NSDictionary *dic = @{NSFontAttributeName:kSystemFont_16, NSParagraphStyleAttributeName:style};
    NSAttributedString *attributeStr = [[NSAttributedString alloc] initWithString:tipStr attributes:dic];
    tipLabel.attributedText = attributeStr;
    tipLabel.numberOfLines = 0;
    CGFloat height = [self getHeightLineWithString:tipStr withWidth:kDeviceWidth - 20 withFont:kSystemFont_16];
    tipLabel.frame = CGRectMake(10, topHeight + 300, kDeviceWidth - 20, height);

#pragma mark - 根据字符串计算label高度
- (CGFloat)getHeightLineWithString:(NSString *)string withWidth:(CGFloat)width withFont:(UIFont *)font {
    
    //1.1最大允许绘制的文本范围
    CGSize size = CGSizeMake(width, 2000);
    //1.2配置计算时的行截取方法,和contentLabel对应
    NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];
    [style setLineSpacing:10];
    //1.3配置计算时的字体的大小
    //1.4配置属性字典
    NSDictionary *dic = @{NSFontAttributeName:font, NSParagraphStyleAttributeName:style};
    //2.计算
    //如果想保留多个枚举值,则枚举值中间加按位或|即可,并不是所有的枚举类型都可以按位或,只有枚举值的赋值中有左移运算符时才可以
    CGFloat height = [string boundingRectWithSize:size options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:dic context:nil].size.height;
    
    return height;
}


### iOS Hook 字符串的技术与方法 在 iOS 平台上,Hook 字符串相关技术主要依赖于动态分析工具(如 Frida)或 Runtime 操作(如 Method Swizzling)。以下是几种实现方式: #### 1. 使用 Frida Hook 字符串 Frida 是一个强大的动态分析工具,支持在运行时拦截和修改函数调用。可以通过 Frida 来 Hook 字符串的创建、比较等操作。 - **字符串创建 Hook**:可以 Hook `NSString` 的初始化方法,例如 `- (id)initWithUTF8String:(const char *)cString` 或者 `+ (id)stringWithUTF8String:(const char *)utf8String`。 ```javascript Interceptor.attach(Module.findExportByName("Foundation", "objc_msgSend"), { onEnter: function(args) { var selector = ObjC.Message(args[0], args[1]).toString(); if (selector === 'initWithUTF8String:') { var utf8String = Memory.readUtf8String(args[2]); console.log("[+] NSString created: " + utf8String); } } }); ``` - **字符串比较 Hook**:可以 Hook `NSString` 的比较方法,例如 `- (BOOL)isEqualToString:(NSString *)aString`。 ```javascript var original = ObjC.classes.NSString["isEqualToString:"]; ObjC.classes.NSString["isEqualToString:"] = ObjC.implement( ObjC.classes.NSString["isEqualToString:"], function(self, sel, otherString) { console.log("[+] Comparing strings:", self.toString(), "with", otherString.toString()); return original(self, sel, otherString); } ); ``` 上述代码通过拦截 `isEqualToString:` 方法,在每次字符串比较时打印出参与比较的两个字符串[^1]。 #### 2. 使用 Method Swizzling Hook 字符串 Method Swizzling 是一种交换 Objective-C 方法实现的技术,可以在不修改原始代码的情况下改变方法的行为。 - **示例:Hook `isEqualToString:` 方法** ```objective-c #import <objc/runtime.h> @implementation NSString (Swizzle) + (void)load { Method originalMethod = class_getInstanceMethod(self, @selector(isEqualToString:)); Method swizzledMethod = class_getInstanceMethod(self, @selector(my_isEqualToString:)); method_exchangeImplementations(originalMethod, swizzledMethod); } - (BOOL)my_isEqualToString:(NSString *)aString { NSLog(@"[+] Original string: %@, compared with: %@", self, aString); return [self my_isEqualToString:aString]; } @end ``` 上述代码通过 Method Swizzling 在每次调用 `isEqualToString:` 时打印出比较的两个字符串[^3]。 #### 3. 使用 fishhook 动态替换符号 fishhook 是一个轻量级的库,允许在运行时替换动态链接符号。可以通过它来 Hook `NSString` 的初始化或比较方法。 - **示例:替换 `-[NSString isEqualToString:]` 方法** ```c #include "fishhook.h" typedef BOOL (*OriginalIsEqualToString)(NSString *self, NSString *other); BOOL my_isEqualToString(NSString *self, NSString *other) { NSLog(@"[+] Hooked isEqualToString: %@ == %@", self, other); return ((OriginalIsEqualToString)dlsym(RTLD_DEFAULT, "objc_msgSend"))(self, @selector(isEqualToString:), other); } struct rebinding rebindings[] = { {"-[NSString isEqualToString:]", (void *)my_isEqualToString, NULL}, }; int main(int argc, const char * argv[]) { rebind_symbols(rebindings, sizeof(rebindings)/sizeof(struct rebinding)); return 0; } ``` 上述代码使用 fishhook 替换了 `-[NSString isEqualToString:]` 方法,在每次调用时打印日志。 #### 4. Hook 特定场景下的字符串操作 如果目标应用中存在特定的字符串操作(例如按钮点击后的验证逻辑),可以通过 Hook 相关方法来捕获字符串。 - **示例:Hook 登录按钮点击逻辑中的字符串比较** 假设登录按钮的点击事件如下所示: ```objective-c - (IBAction)btn1Click:(id)sender { if ([self.tf.text isEqualToString:@"9527"]) { self.label1.text = @"请输入密码"; } else { self.label1.text = @"密码错误,重新输入"; } } ``` 可以通过 Hook `btn1Click:` 方法来捕获输入的字符串: ```javascript Interceptor.attach(ObjC.classes.YourViewController["btn1Click:"].implementation, { onEnter: function(args) { var sender = ObjC.Object(args[2]); var tfText = ObjC.classes.YourViewController.tf.text.toString(); console.log("[+] Button clicked, text field value: " + tfText); } }); ``` 上述代码通过拦截 `btn1Click:` 方法,在每次按钮点击时打印出文本框的值[^5]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值