gpt4 book ai didi

ios - 扩展 UIView 以自动添加标签(或执行另一个初始化操作)

转载 作者:行者123 更新时间:2023-11-30 14:10:56 26 4
gpt4 key购买 nike

最近在工作中,我的任务是组装一个应用程序,以编程方式而不是通过 Storyboard创建其所有 View 。在大多数情况下,除了运行应用程序和调整 View 之间的更多来回之外,这种方法效果很好。作为一个有趣的业余项目,我想构建一个“调试”套件来帮助那些有同样想法的人。

在对齐/样式方面真正帮助我的是一个类似 css 样式的第三方库 ( http://classy.as ),它允许我在将以下代码片段添加到样式表后看到每个图层/ View 的边界:

^UIView {
layer: @{
borderWidth: 1;
}
}

我想要类似的东西,但在左上角附加一个标签,命名组件的类名。实际上,我想要的是每个 UIView 上自动生成和自动附加的标签,最好是可以通过变量切换的标签(即 debugLabel)。我尝试通过以下代码来实现这一目标:

private var debugLabelsEnabled: Bool = false
extension UIView {
@IBInspectable var debugLabel: Bool! {
get {
return objc_getAssociatedObject(self, &debugLabelsEnabled) as? Bool
}
set(value) {
objc_setAssociatedObject(self, &debugLabelsEnabled, value, objc_AssociationPolicy(OBJC_ASSOCIATION_RETAIN))
let label = UILabel(frame: CGRect(origin: self.frame.origin, size: CGSize(width: 100, height: 15)))
label.text = _stdlib_getDemangledTypeName(self)
label.font = UIFont(name: "Courier", size: 9)
self.addSubview(label)
}
}
}

然后,我尝试通过 Classy 测试上述代码片段,方法是在 ^UIView 上设置 debugLabel 。那没有效果。但是,单独设置 myView.debugLabel = true 确实有效。不幸的是,我不能指望开发人员在每个 View 上手动设置此属性。我想要一些符合 Classy 逻辑的东西,我可以为 View 中的所有元素(以及稍后可能出现的元素)切换该标签。

我基本上想做的是修改所有 UIView 的初始化逻辑,以执行额外的操作,而无需子类化(因为我希望从 UIView 继承的所有现有元素自动执行此逻辑)。 有人可以帮我吗?有没有一种明智的方法来实现这一目标?我正在考虑进入 Root View Controller ,然后递归地迭代其所有 subview ,但这不会像 Classy 那样处理当前未显示的 View 。如果需要的话,我不介意为此切换到 Obj-C,但是,我更愿意将其余逻辑保留在 Swift 中。

最佳答案

据我所知,UIView 只有 2 个有用的 init,因此您可以通过使用 convenience 轻松实现您想要的效果。初始化。

class FancyView : UIView {
var foo = 0
}

extension UIView {
convenience init(frame : CGRect?, addDebugThings: Bool) {

if frame != nil {
self.init(frame: frame!)
} else {
self.init()
}

if addDebugThings {
addLabel()
}

}

private func addLabel() {
println("add label")
}
}

let view = UIView(frame: nil, addDebugThings: true)
let fancy = FancyView(frame: CGRectMake(0.0, 35.0, 350.0, 350.0), addDebugThings: false)

<罢工>

编辑:正如您指出的,它不适用于 UIView 子类,我建议的另一种方法是方法调配,但不幸的是,这需要迁移到 Obj-C。

这是一个如何轻松做到这一点的示例。

UIView+Border.h:

#import <Foundation/Foundation.h>
@interface UIView(Border)
@end

UIView+Border.m:

#import "UIView+Border.h"
#import <QuartzCore/QuartzCore.h>
#import <objc/runtime.h>

@implementation UIView(Border)

- (id)swizzled_initWithFrame:(CGRect)frame
{
// You might think it is an endless recursion but it is not.
id result = [self swizzled_initWithFrame:frame];

// Safe guard: do we have an UIView (or something that has a layer)?
if ([result respondsToSelector:@selector(layer)]) {
// Get layer for this view.
CALayer *layer = [result layer];
// Set border on layer.
layer.borderWidth = 2;
layer.borderColor = [[UIColor redColor] CGColor];
}

// Return the modified view.
return result;
}

- (id)swizzled_initWithCoder:(NSCoder *)aDecoder
{
// You might think it is an endless recursion but it is not.
id result = [self swizzled_initWithCoder:aDecoder];

// Safe guard: do we have an UIView (or something that has a layer)?
if ([result respondsToSelector:@selector(layer)]) {
// Get layer for this view.
CALayer *layer = [result layer];
// Set border on layer.
layer.borderWidth = 2;
layer.borderColor = [[UIColor blueColor] CGColor];
}

// Return the modified view.
return result;
}

+ (void)load
{
// The "+ load" method is called once, very early in the application life-cycle.
// It's called even before the "main" function is called. Beware: there's no
// autorelease pool at this point, so avoid Objective-C calls.
Method original, swizzle;

// Get the "- (id)initWithFrame:" method.
original = class_getInstanceMethod(self, @selector(initWithFrame:));
// Get the "- (id)swizzled_initWithFrame:" method.
swizzle = class_getInstanceMethod(self, @selector(swizzled_initWithFrame:));
// Swap their implementations.
method_exchangeImplementations(original, swizzle);

// Get the "- (id)initWithCoder:" method.
original = class_getInstanceMethod(self, @selector(initWithCoder:));
// Get the "- (id)swizzled_initWithCoder:" method.
swizzle = class_getInstanceMethod(self, @selector(swizzled_initWithCoder:));
// Swap their implementations.
method_exchangeImplementations(original, swizzle);
}

@end

关于ios - 扩展 UIView 以自动添加标签(或执行另一个初始化操作),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31773903/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com