如何修改第三方库

简介: 如何修改第三方库

修改第三方库最简单的是拖入工程直接修改。当然由于库间引用,导致拖入工程修改需要处理很多编译问题。指定版本后修改本地库,若别人使用时下载的库和自己的不一样。那如何不拖入工程,并且别人也能使用我们修改后的库呢?需要指定版本然后用分类。以带SceneDelegate的工程SVProgressHUD弹出框显示在左上角为例子进行解说。

一般的分类是指重载方法,不定义属性。其实分类也可以定义并使用属性。只是要想分类定义属性要自己实现setter方法和getter方法。

//给刷新控件设置 setter  getter 方法

static char * HudView = "HudView";

设置getter方法:

- (UIVisualEffectView *)hudView {

    //如果属性值是非id类型,可以通过属性值先构造OC的id对象,再通过对象获取非id类型属性
    return objc_getAssociatedObject(self, HudView);

}
//运行时实现setter方法

- (void)setHudView:(UIVisualEffectView*)hudView{

    objc_setAssociatedObject(self, HudView, hudView, OBJC_ASSOCIATION_RETAIN);

}

具体完整例子如下:

指定SVProgressHUD版本号:pod 'SVProgressHUD', '2.2.5'

SVProgressHUD+DYExtension.h文件:

#import <UIKit/UIKit.h>
#import "SVProgressHUD.h"

@interface SVProgressHUD (DYExtension)

@property (nonatomic, strong) UIVisualEffectView *hudView;
- (void)positionHUD:(NSNotification*)notification;
@end

SVProgressHUD+DYExtension.m文件:

#import "SVProgressHUD+DYExtension.h"
#import "SVIndefiniteAnimatedView.h"
#import "SVProgressAnimatedView.h"
#import "SVRadialGradientLayer.h"
#import<objc/runtime.h>

//给刷新控件设置 setter  getter 方法

static char * HudView = "HudView";

static const CGFloat SVProgressHUDParallaxDepthPoints = 10.0f;
static const CGFloat SVProgressHUDUndefinedProgress = -1;
static const CGFloat SVProgressHUDDefaultAnimationDuration = 0.15f;
static const CGFloat SVProgressHUDVerticalSpacing = 12.0f;
static const CGFloat SVProgressHUDHorizontalSpacing = 12.0f;
static const CGFloat SVProgressHUDLabelSpacing = 8.0f;

@implementation SVProgressHUD (DYExtension)

- (UIVisualEffectView *)hudView {

    //如果属性值是非id类型,可以通过属性值先构造OC的id对象,再通过对象获取非id类型属性
    return objc_getAssociatedObject(self, HudView);

}

//运行时实现setter方法

- (void)setHudView:(UIVisualEffectView*)hudView{

    objc_setAssociatedObject(self, HudView, hudView, OBJC_ASSOCIATION_RETAIN);

}


- (void)positionHUD:(NSNotification*)notification {
    CGFloat keyboardHeight = 0.0f;
    double animationDuration = 0.0;

#if !defined(SV_APP_EXTENSIONS) && TARGET_OS_IOS
    self.frame = [UIApplication sharedApplication].keyWindow.bounds;
    UIInterfaceOrientation orientation = UIApplication.sharedApplication.statusBarOrientation;
#elif !defined(SV_APP_EXTENSIONS) && !TARGET_OS_IOS
    self.frame= [UIApplication sharedApplication].keyWindow.bounds;
#else
    if (self.viewForExtension) {
        self.frame = self.viewForExtension.frame;
    } else {
        self.frame = UIScreen.mainScreen.bounds;
    }
#if TARGET_OS_IOS
    UIInterfaceOrientation orientation = CGRectGetWidth(self.frame) > CGRectGetHeight(self.frame) ? UIInterfaceOrientationLandscapeLeft : UIInterfaceOrientationPortrait;
#endif
#endif
    
#if TARGET_OS_IOS
    // Get keyboardHeight in regard to current state
    if(notification) {
        NSDictionary* keyboardInfo = [notification userInfo];
        CGRect keyboardFrame = [keyboardInfo[UIKeyboardFrameBeginUserInfoKey] CGRectValue];
        animationDuration = [keyboardInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
        
        if(notification.name == UIKeyboardWillShowNotification || notification.name == UIKeyboardDidShowNotification) {
            keyboardHeight = CGRectGetWidth(keyboardFrame);
            
            if(UIInterfaceOrientationIsPortrait(orientation)) {
                keyboardHeight = CGRectGetHeight(keyboardFrame);
            }
        }
    } else {
        keyboardHeight = self.visibleKeyboardHeight;
    }
#endif
    
    // Get the currently active frame of the display (depends on orientation)
    CGRect orientationFrame = self.bounds;

#if !defined(SV_APP_EXTENSIONS) && TARGET_OS_IOS
    CGRect statusBarFrame = UIApplication.sharedApplication.statusBarFrame;
#else
    CGRect statusBarFrame = CGRectZero;
#endif
    
#if TARGET_OS_IOS
    // Update the motion effects in regard to orientation
    [self updateMotionEffectForOrientation:orientation];
#else
    [self updateMotionEffectForXMotionEffectType:UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis yMotionEffectType:UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis];
#endif
    
    // Calculate available height for display
    CGFloat activeHeight = CGRectGetHeight(orientationFrame);
    if(keyboardHeight > 0) {
        activeHeight += CGRectGetHeight(statusBarFrame) * 2;
    }
    activeHeight -= keyboardHeight;
    
    CGFloat posX = CGRectGetMidX(orientationFrame);
    CGFloat posY = floorf(activeHeight*0.45f);

    CGFloat rotateAngle = 0.0;
    CGPoint newCenter = CGPointMake(posX, posY);
    
    if(notification) {
        // Animate update if notification was present
        [UIView animateWithDuration:animationDuration
                              delay:0
                            options:(UIViewAnimationOptions) (UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionBeginFromCurrentState)
                         animations:^{
                             [self moveToPoint:newCenter rotateAngle:rotateAngle];
                             [[self getHudView] setNeedsDisplay];
                         } completion:nil];
    } else {
        [self moveToPoint:newCenter rotateAngle:rotateAngle];
    }
}
- (void)moveToPoint:(CGPoint)newCenter rotateAngle:(CGFloat)angle {
    [self getHudView].transform = CGAffineTransformMakeRotation(angle);
    if (self.containerView) {
        [self getHudView].center = CGPointMake(self.containerView.center.x + self.offsetFromCenter.horizontal, self.containerView.center.y + self.offsetFromCenter.vertical);
    } else {
        [self getHudView].center = CGPointMake(newCenter.x + self.offsetFromCenter.horizontal, newCenter.y + self.offsetFromCenter.vertical);
    }
}

#if TARGET_OS_IOS
- (void)updateMotionEffectForOrientation:(UIInterfaceOrientation)orientation {
    UIInterpolatingMotionEffectType xMotionEffectType = UIInterfaceOrientationIsPortrait(orientation) ? UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis : UIInterpolatingMotionEffectTypeTiltAlongVerticalAxis;
    UIInterpolatingMotionEffectType yMotionEffectType = UIInterfaceOrientationIsPortrait(orientation) ? UIInterpolatingMotionEffectTypeTiltAlongVerticalAxis : UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis;
    [self updateMotionEffectForXMotionEffectType:xMotionEffectType yMotionEffectType:yMotionEffectType];
}
#endif
- (void)updateMotionEffectForXMotionEffectType:(UIInterpolatingMotionEffectType)xMotionEffectType yMotionEffectType:(UIInterpolatingMotionEffectType)yMotionEffectType {
    UIInterpolatingMotionEffect *effectX = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"center.x" type:xMotionEffectType];
    effectX.minimumRelativeValue = @(-SVProgressHUDParallaxDepthPoints);
    effectX.maximumRelativeValue = @(SVProgressHUDParallaxDepthPoints);
    
    UIInterpolatingMotionEffect *effectY = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"center.y" type:yMotionEffectType];
    effectY.minimumRelativeValue = @(-SVProgressHUDParallaxDepthPoints);
    effectY.maximumRelativeValue = @(SVProgressHUDParallaxDepthPoints);
    
    UIMotionEffectGroup *effectGroup = [UIMotionEffectGroup new];
    effectGroup.motionEffects = @[effectX, effectY];
    
    // Clear old motion effect, then add new motion effects
    [self getHudView].motionEffects = @[];
    [[self getHudView] addMotionEffect:effectGroup];
}
- (UIVisualEffectView*)getHudView {
    if(!self.hudView) {
        self.hudView = [UIVisualEffectView new];
        self.hudView.layer.masksToBounds = YES;
        self.hudView.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleLeftMargin;
    }
    if(!self.hudView.superview) {
        [self addSubview:self.hudView];
    }

    // Update styling
    self.hudView.layer.cornerRadius = self.cornerRadius;

    return self.hudView;
}


- (CGFloat)visibleKeyboardHeight {
#if !defined(SV_APP_EXTENSIONS)
    UIWindow *keyboardWindow = nil;
    for (UIWindow *testWindow in UIApplication.sharedApplication.windows) {
        if(![testWindow.class isEqual:UIWindow.class]) {
            keyboardWindow = testWindow;
            break;
        }
    }
    
    for (__strong UIView *possibleKeyboard in keyboardWindow.subviews) {
        NSString *viewName = NSStringFromClass(possibleKeyboard.class);
        if([viewName hasPrefix:@"UI"]){
            if([viewName hasSuffix:@"PeripheralHostView"] || [viewName hasSuffix:@"Keyboard"]){
                return CGRectGetHeight(possibleKeyboard.bounds);
            } else if ([viewName hasSuffix:@"InputSetContainerView"]){
                for (__strong UIView *possibleKeyboardSubview in possibleKeyboard.subviews) {
                    viewName = NSStringFromClass(possibleKeyboardSubview.class);
                    if([viewName hasPrefix:@"UI"] && [viewName hasSuffix:@"InputSetHostView"]) {
                        CGRect convertedRect = [possibleKeyboard convertRect:possibleKeyboardSubview.frame toView:self];
                        CGRect intersectedRect = CGRectIntersection(convertedRect, self.bounds);
                        if (!CGRectIsNull(intersectedRect)) {
                            return CGRectGetHeight(intersectedRect);
                        }
                    }
                }
            }
        }
    }
#endif
    return 0;
}
@end
目录
相关文章
|
6月前
|
Python
python中导入模块/包的几种方式
python中导入模块/包的几种方式
67 0
|
14天前
|
JavaScript 前端开发 API
vue3中常用插件的使用方法:按需引入自定义组件,自动导入依赖包,自动生成路由,自动生成模拟数据
vue3中常用插件的使用方法:按需引入自定义组件,自动导入依赖包,自动生成路由,自动生成模拟数据
321 0
|
3月前
|
JSON JavaScript IDE
[译] 使用 microbundle 打包 TypeScript 组件库
[译] 使用 microbundle 打包 TypeScript 组件库
|
6月前
|
数据采集 JavaScript 前端开发
TypeScript 和 jsdom 库创建爬虫程序示例
TypeScript 和 jsdom 库创建爬虫程序示例
|
Python
python中动态导入文件的方法
python中动态导入文件的方法
334 0
python中动态导入文件的方法
|
6月前
|
程序员 C++
C++中第三方库的一般使用方式(libxl库为例)
C++中第三方库的一般使用方式(libxl库为例)
445 0
|
6月前
|
Python
【Python基础】模块的概念、模块的导入和下载第三方模块
【Python基础】模块的概念、模块的导入和下载第三方模块
|
6月前
|
前端开发 JavaScript 开发者
探索npm的高级特性:自定义脚本与包的发布与维护
探索npm的高级特性:自定义脚本与包的发布与维护
|
缓存 前端开发 JavaScript
前端封装库/工具库的实用工具库之Lodash
当今,前端开发已经成为了互联网行业中的主流技术之一。在大多数项目中,我们都需要用到很多的 JavaScript 工具库来提供便利的操作和优化性能。其中一个非常流行的 JavaScript 工具库是 Lodash。 Lodash 是一个一致性、模块化、高性能的 JavaScript 实用工具库。它提供了对数组、数字、对象、字符串等常用数据类型的处理方法,并且支持链式调用和函数式编程风格,优化了 JavaScript 应用的性能和可读性。
363 1
|
JSON 小程序 前端开发
小程序引入第三方插件Vant和小程序WeUl组件库
现如今前端的技术再向框架化的发展,框架的使用提高我们的编码的效率和性能的优化,同样CSS样式也是越来越高的要求,今天我要向大家介绍的就是较火的前端UI框架Vant UI组件库
263 0