91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

iOS開發:UILabel字號根據屏幕縮放

發布時間:2020-07-18 02:28:06 來源:網絡 閱讀:767 作者:PSPDF 欄目:移動開發

場景:

假設我們有這樣一個需求,iPhone 6(屏幕寬度為375pt)上的設計圖上的字號為17pt,iPhone 6 Plus上的字號根據屏幕寬度縮放,即字號為(17pt x 414pt / 375pt)= 18.768pt

解決方案:

如果一個一個設置太麻煩,容易遺漏,這時候我們采用 runtime 的替換方法來實現,如果嫌替換方法太麻煩,我們可以用第三方庫 Aspects 來輔助我們解決。

步驟:

  1. 添加pod

    pod 'Aspects', '~> 1.4.1'
  2. 新建UILabel Category,命名為UILabel+AspectsScaling
    以下為文件內容
    UILabel+AspectsScaling.h 文件
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface UILabel (AspectsScaling)
@end
NS_ASSUME_NONNULL_END

UILabel+AspectsScaling.m 文件

#import "UILabel+AspectsScaling.h"
#import "Aspects.h"
@implementation UILabel (AspectsScaling)
+ (void)load {
  NSError * error = nil;
  [self aspect_hookSelector:@selector(initWithCoder:) withOptions:AspectPositionAfter usingBlock:^(id<AspectInfo> info, NSCoder * coder) {
    [info.instance scaleFont];
  } error:&error];
  [self aspect_hookSelector:@selector(initWithFrame:) withOptions:AspectPositionAfter usingBlock:^(id<AspectInfo> info, CGRect frame) {
    [info.instance scaleFont];
  } error:&error];
  //以下是log方法,可以不要
#if DEBUG
  [self aspect_hookSelector:@selector(scaleFont) withOptions:AspectPositionBefore usingBlock:^(id<AspectInfo> info) {
    UILabel * label = info.instance;
    NSLog(@"UILabel: Before Scaling font size: %f", label.font.pointSize);
  } error:&error];
  [self aspect_hookSelector:@selector(scaleFont) withOptions:AspectPositionAfter usingBlock:^(id<AspectInfo> info) {
    UILabel * label = info.instance;
    NSLog(@"UILabel: After Scaling font size: %f", label.font.pointSize);
  } error:&error];
#endif
}
- (void)scaleFont {
  CGFloat ratio = CGRectGetWidth(UIScreen.mainScreen.bounds) / (CGFloat)375;
  self.font = [UIFont fontWithDescriptor:self.font.fontDescriptor size:self.font.pointSize * ratio];
}
@end

解釋:

  1. 顯然,這是縮放字體的方法
    - (void)scaleFont;
  2. 這個方法是在原來的initWithCoder: 方法后面執行一個 block ,這是 Aspects 庫的方法,利用的是 runtime,可以自行了解源碼
    [self aspect_hookSelector:@selector(initWithCoder:) withOptions:AspectPositionAfter usingBlock:^(id<AspectInfo> info, NSCoder * coder)...
  3. 再看 log 方法,這個 log 方法利用 Aspects ,在替換字體前后 NSLog 字體的字號,這個區別在參數 AspectPositionBefore 和 AspectPositionAfter
    [self aspect_hookSelector:@selector(scaleFont) withOptions:AspectPositionBefore usingBlock:^(id<AspectInfo> info) ...
    [self aspect_hookSelector:@selector(scaleFont) withOptions:AspectPositionAfter usingBlock:^(id<AspectInfo> info) ...
  4. 我們看看 Aspects 的Aspects.h文件:
    里面提供兩個方法,
    • 一個是類方法(修改類的所有實例的方法),
    • 一個是實例方法(修改單個實例的方法),
    • 返回值是一個id<AspectToken>可以保存以后取消修改,
    • usingBlock:(id)block 里面的類型id一般情況下可以寫成^(id<AspectInfo> info, ...) ...是要修改的方法的所有參數,如@selector(initWithFrame:) ,block 類型^(id<AspectInfo> info, CGRect frame)
...
typedef NS_OPTIONS(NSUInteger, AspectOptions) {
    AspectPositionAfter   = 0,            /// Called after the original implementation (default)
    AspectPositionInstead = 1,            /// Will replace the original implementation.
    AspectPositionBefore  = 2,            /// Called before the original implementation.

    AspectOptionAutomaticRemoval = 1 << 3 /// Will remove the hook after the first execution.
};
...
+ (id<AspectToken>)aspect_hookSelector:(SEL)selector
                      withOptions:(AspectOptions)options
                       usingBlock:(id)block
                            error:(NSError **)error;

/// Adds a block of code before/instead/after the current `selector` for a specific instance.
- (id<AspectToken>)aspect_hookSelector:(SEL)selector
                      withOptions:(AspectOptions)options
                       usingBlock:(id)block
                            error:(NSError **)error;
...

總結

Aspects 是 iOS Aspect-oriented programming (AOP) 的一種實現,
滿足以下幾點就可以使用(但不是必須滿足才能使用)

  • 原來要有實例方法實現
  • 頻繁調用,一個一個修改太麻煩
  • 在原來的實例方法的前面和后面可以插入代碼完成需求
  • 最最常用的是log,以后可以一步注釋
[UIViewController aspect_hookSelector:@selector(viewWillAppear:) withOptions:AspectPositionAfter usingBlock:^(id<AspectInfo> aspectInfo, BOOL animated) {
    NSLog(@"View Controller %@ will appear animated: %tu", aspectInfo.instance, animated);
} error:NULL];

Aspects 不是萬能的,GitHub項目主頁有Compatibility and Limitations ,一種常見的問題是當攔截一個方法的時候,它會把相關類當作已攔截,就會報錯(A method can only be hooked once per class hierarchy ),所以當方法名相同時要考慮其他方法,這個 Aspects 庫無法滿足需求

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

和静县| 集安市| 鄂尔多斯市| 兴仁县| 临城县| 阿图什市| 黄陵县| 张家口市| 中宁县| 虎林市| 南充市| 壶关县| 博罗县| 甘洛县| 曲麻莱县| 上蔡县| 大足县| 安新县| 开化县| 阳谷县| 东源县| 连云港市| 漯河市| 南漳县| 福安市| 章丘市| 建德市| 永和县| 麟游县| 墨脱县| 卫辉市| 长岭县| 黎城县| 广汉市| 油尖旺区| 神农架林区| 铜鼓县| 新宾| 富锦市| 益阳市| 鄯善县|