将全局 class 应用于 UIImage
Apply global class to UIImage
现在我不确定这在 Objective-C 中是否可行,但我希望它应该可行。
我使用 UIImages
上的 following/similar 代码在我的故事板上有多张图片
cell.followingImage.layer.cornerRadius = cell.followingImage.frame.size.width / 2;
cell.followingImage.clipsToBounds = YES;
我想优化代码。我知道您可以将 classes 应用于对象,但我以前从未这样做过。是否可以通过故事板应用 class 并自动 运行 该代码而不引用并将其添加到每个控制器?
因此,如果 class 附加到 UIImage
,它只会 运行 该代码并使 UIImage
成为一个圆圈?这可能真的很简单...
如果我要子class 一个 UIimage 我不知道把上面的代码放在哪里?
尝试制作一个UIImage的类别。在此自定义类别 class 中包含您想要的所有内容,例如 cornerRadius 和 clipToBounds 代码。然后,当您初始化图像时,不要使用 [UIImage new] 而是使用 [customImageCategoryName new[.现在,默认情况下,所有这些图像都将包含这两行代码。以下link将向您展示如何在XcodeHow do I create a category in Xcode 6 or higher?
中创建类别
请将该代码放入
-(instancetype)initWithCoder:(NSCoder *)aDecoder
方法 , -(instancetype)initWithFrame:(CGRect)frame
方法
和 init
方法。
这样,如果 imageview 来自故事板,将调用 initWithCoder 并在以编程方式添加时调用其他方法。
由于 none 的其他答案确实有效但不够完整,所以我改用了 User Defined Runtime Attributes
。
为了避免在代码中编写它,我添加了
layer.cornerRadius
Number
属性宽度的一半。
layer.masksToBounds
Bool
属性为 YES
您的 "answer" 表明您在 Storyboard 中使用了 UIImageView
。最好的方法是创建 UIImageView
的子 class,例如:
//MyImageView.h
#import <UIKit/UIKit.h>
@interface MyImageView : UIImageView
@end
适配 cornerRadius
和 clipsToBounds
的代码应添加到 MyImageView.m:
//MyImageView.m
- (id)layoutSubviews {
[super layoutSubviews];
self.layer.cornerRadius = self.view.frame.width.width / 2
self.layer.clipsToBounds = true;
// this line may be only needed in init since the clipsToBounds does not change due to autoLayout.
}
编写该代码后,您需要将 Storyboard 中所有 UIImageView
的 class 属性(所有应该是循环的)设置为 MyImageView
而不是默认值UIImageView
.
方法混合是实现这一目标的一个很好的选择。
创建一个 UIImageView 类别 class 并调整 initWithCoder: 方法
#import "UIImageView+MethodSwizzling.h"
#import <objc/runtime.h>
@implementation UIImageView (MethodSwizzling)
+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Class class = [self class];
SEL originalSelector = @selector(initWithCoder:);
SEL swizzledSelector = @selector(xxx_initWithCoder:);
Method originalMethod = class_getInstanceMethod(class, originalSelector);
Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
// When swizzling a class method, use the following:
// Class class = object_getClass((id)self);
// ...
// Method originalMethod = class_getClassMethod(class, originalSelector);
// Method swizzledMethod = class_getClassMethod(class, swizzledSelector);
BOOL didAddMethod =
class_addMethod(class,
originalSelector,
method_getImplementation(swizzledMethod),
method_getTypeEncoding(swizzledMethod));
if (didAddMethod) {
class_replaceMethod(class,
swizzledSelector,
method_getImplementation(originalMethod),
method_getTypeEncoding(originalMethod));
}
else {
method_exchangeImplementations(originalMethod, swizzledMethod);
}
});
}
#pragma mark - Method Swizzling
- (id)xxx_initWithCoder:(NSCoder*)aDecoder {
[self xxx_initWithCoder:aDecoder];
self.layer.cornerRadius = self.frame.size.width / 2;
self.layer.masksToBounds = YES;
NSLog(@"xxx_initWithCoder: %@", self);
return self;
}
您不必创建 UIImageView 的子class,也不需要在 XIB/Storybord.
中的任何地方更改对象的 class
Click here 了解方法调配。
现在我不确定这在 Objective-C 中是否可行,但我希望它应该可行。
我使用 UIImages
cell.followingImage.layer.cornerRadius = cell.followingImage.frame.size.width / 2;
cell.followingImage.clipsToBounds = YES;
我想优化代码。我知道您可以将 classes 应用于对象,但我以前从未这样做过。是否可以通过故事板应用 class 并自动 运行 该代码而不引用并将其添加到每个控制器?
因此,如果 class 附加到 UIImage
,它只会 运行 该代码并使 UIImage
成为一个圆圈?这可能真的很简单...
如果我要子class 一个 UIimage 我不知道把上面的代码放在哪里?
尝试制作一个UIImage的类别。在此自定义类别 class 中包含您想要的所有内容,例如 cornerRadius 和 clipToBounds 代码。然后,当您初始化图像时,不要使用 [UIImage new] 而是使用 [customImageCategoryName new[.现在,默认情况下,所有这些图像都将包含这两行代码。以下link将向您展示如何在XcodeHow do I create a category in Xcode 6 or higher?
中创建类别请将该代码放入
-(instancetype)initWithCoder:(NSCoder *)aDecoder
方法 , -(instancetype)initWithFrame:(CGRect)frame
方法
和 init
方法。
这样,如果 imageview 来自故事板,将调用 initWithCoder 并在以编程方式添加时调用其他方法。
由于 none 的其他答案确实有效但不够完整,所以我改用了 User Defined Runtime Attributes
。
为了避免在代码中编写它,我添加了
layer.cornerRadius
Number
属性宽度的一半。
layer.masksToBounds
Bool
属性为 YES
您的 "answer" 表明您在 Storyboard 中使用了 UIImageView
。最好的方法是创建 UIImageView
的子 class,例如:
//MyImageView.h
#import <UIKit/UIKit.h>
@interface MyImageView : UIImageView
@end
适配 cornerRadius
和 clipsToBounds
的代码应添加到 MyImageView.m:
//MyImageView.m
- (id)layoutSubviews {
[super layoutSubviews];
self.layer.cornerRadius = self.view.frame.width.width / 2
self.layer.clipsToBounds = true;
// this line may be only needed in init since the clipsToBounds does not change due to autoLayout.
}
编写该代码后,您需要将 Storyboard 中所有 UIImageView
的 class 属性(所有应该是循环的)设置为 MyImageView
而不是默认值UIImageView
.
方法混合是实现这一目标的一个很好的选择。 创建一个 UIImageView 类别 class 并调整 initWithCoder: 方法
#import "UIImageView+MethodSwizzling.h"
#import <objc/runtime.h>
@implementation UIImageView (MethodSwizzling)
+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Class class = [self class];
SEL originalSelector = @selector(initWithCoder:);
SEL swizzledSelector = @selector(xxx_initWithCoder:);
Method originalMethod = class_getInstanceMethod(class, originalSelector);
Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
// When swizzling a class method, use the following:
// Class class = object_getClass((id)self);
// ...
// Method originalMethod = class_getClassMethod(class, originalSelector);
// Method swizzledMethod = class_getClassMethod(class, swizzledSelector);
BOOL didAddMethod =
class_addMethod(class,
originalSelector,
method_getImplementation(swizzledMethod),
method_getTypeEncoding(swizzledMethod));
if (didAddMethod) {
class_replaceMethod(class,
swizzledSelector,
method_getImplementation(originalMethod),
method_getTypeEncoding(originalMethod));
}
else {
method_exchangeImplementations(originalMethod, swizzledMethod);
}
});
}
#pragma mark - Method Swizzling
- (id)xxx_initWithCoder:(NSCoder*)aDecoder {
[self xxx_initWithCoder:aDecoder];
self.layer.cornerRadius = self.frame.size.width / 2;
self.layer.masksToBounds = YES;
NSLog(@"xxx_initWithCoder: %@", self);
return self;
}
您不必创建 UIImageView 的子class,也不需要在 XIB/Storybord.
中的任何地方更改对象的 classClick here 了解方法调配。