わかりました、これはありますが、機能しません:
@interface UILabel (touches)
@property (nonatomic) BOOL isMethodStep;
@end
@implementation UILabel (touches)
-(BOOL)isMethodStep {
return self.isMethodStep;
}
-(void)setIsMethodStep:(BOOL)boolean {
self.isMethodStep = boolean;
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
if(self.isMethodStep){
// set all labels to normal font:
UIFont *toSet = (self.font == [UIFont fontWithName:@"Helvetica" size:16]) ? [UIFont fontWithName:@"Helvetica-Bold" size:16] : [UIFont fontWithName:@"Helvetica" size:16];
id superView = self.superview;
for(id theView in [(UIView *)superView subviews])
if([theView isKindOfClass:[UILabel class]])
[(UILabel *)theView setFont:[UIFont fontWithName:@"Helvetica" size:16]];
self.font = toSet;
}
}
@end
Getterメソッドとsetterメソッドを削除すると、機能しなくなり、いくつかのgetterメソッドとsetterメソッドを作成する必要があることがわかります(または@synthesizeを使用しますが、@ implementationに@synthesizeを入れるとエラーもスローされます)。しかし、getterメソッドとsetterメソッドを使用すると、EXC_BAD_ACCESSとクラッシュが発生します。何か案は?ありがとう
トム
カテゴリを介して既存のクラスにメンバーとプロパティを追加することはできません。メソッドのみです。
考えられる回避策の1つは、シングルトンを使用して変数を保存する「セッター/ゲッターのような」メソッドを作成することです。これは、メンバーでした。
-(void)setMember:(MyObject *)someObject
{
NSMutableDictionary *dict = [MySingleton sharedRegistry];
[dict setObject:someObject forKey:self];
}
-(MyObject *)member
{
NSMutableDictionary *dict = [MySingleton sharedRegistry];
return [dict objectforKey:self];
}
または—もちろん—UILabelから継承するカスタムクラスを作成します
最近では、関連オブジェクトを実行時に挿入できることに注意してください。 Objective Cプログラミング言語:連想参照
すべての回答を確認しましたが、最も一般的な解決策は見つかりませんでした。
#import <objc/runtime.h>
static void const *key;
@interface ClassName (CategoryName)
@property (nonatomic) BOOL myProperty;
@end
@implementation ClassName (CategoryName)
- (BOOL)myProperty {
return [objc_getAssociatedObject(self, key) boolValue];
}
- (void)setMyProperty:(BOOL)value {
objc_setAssociatedObject(self, key, @(value), OBJC_ASSOCIATION_RETAIN);
}
@end
迅速:
private struct AssociatedKeys {
static var keyName = "keyName"
}
extension Foo {
var bar: Any! {
get {
return objc_getAssociatedObject(self, &AssociatedKeys.keyName)
}
set {
objc_setAssociatedObject(self, &AssociatedKeys.keyName , newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
}
}
実行時に関連するオブジェクトを挿入できます。
#import <objc/runtime.h>
@interface UIView (Private)
@property (nonatomic, assign) CGPoint initialTouchPoint;
@property (nonatomic, strong) UIWindow *alertWindow;
@end
@implementation UIView (Private)
@dynamic initialTouchPoint, alertWindow;
- (CGPoint)initialTouchPoint {
return CGPointFromString(objc_getAssociatedObject(self, @selector(initialTouchPoint)));
}
- (void)setInitialTouchPoint:(CGPoint)initialTouchPoint {
objc_setAssociatedObject(self, @selector(initialTouchPoint), NSStringFromCGPoint(initialTouchPoint), OBJC_ASSOCIATION_RETAIN);
}
- (void)setAlertWindow:(UIWindow *)alertWindow {
objc_setAssociatedObject(self, @selector(alertWindow), alertWindow, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (UIWindow *)alertWindow {
return objc_getAssociatedObject(self, @selector(alertWindow));
}
@end
実際には、理想的ではないかもしれませんが、機能する方法があります。
これを機能させるには、クラスXのカテゴリを作成する必要があり、同じXのサブクラスでのみ使用できます(例:category UIView (Background)
canクラスMyView : UIView
で使用できますが、UIView
で直接使用することはできません)
// UIView+Background.h
@interface UIView (Background)
@property (strong, nonatomic) NSString *hexColor;
- (void)someMethodThatUsesHexColor;
@end
// UIView+Background.h
@implementation UIView (Background)
@dynamic hexColor; // Must be declared as dynamic
- (void)someMethodThatUsesHexColor {
NSLog(@"Color %@", self.hexColor);
}
@end
次に
// MyView.m
#import "UIView+Background.h"
@interface MyView : UIView
@property (strong, nonatomic) NSString *hexColor;
@end
@implementation MyView ()
- (void)viewDidLoad {
[super viewDidLoad];
[self setHexColor:@"#BABACA"];
[self someMethodThatUsesHexColor];
}
@end
このメソッドを使用すると、プロパティを「再宣言」する必要がありますが、その後、カテゴリ内ですべての操作を行うことができます。
Xcode 7(7.0.1、7A1001)以降、プロパティはカテゴリでサポートされているようです。 XcodeがCore Dataサブクラスのカテゴリを生成することに気づきました。
たとえば、次のファイルを取得しました。
Location + CoreDataProperties.h
#import "Location.h"
NS_ASSUME_NONNULL_BEGIN
@interface Location (CoreDataProperties)
@property (nullable, nonatomic, retain) NSNumber *altitude;
@property (nullable, nonatomic, retain) NSNumber *latitude;
@property (nullable, nonatomic, retain) NSNumber *longitude;
@end
NS_ASSUME_NONNULL_END
Location + CoreDataProperties.m
#import "Location+CoreDataProperties.h"
@implementation Location (CoreDataProperties)
@dynamic altitude;
@dynamic latitude;
@dynamic longitude;
@end
したがって、カテゴリ内のプロパティが機能するようになりました。非Core Dataクラスではテストしていません。
私が気付いたのは、カテゴリファイルが元のクラスに含まれていることです。
Location.h
@interface Location : NSManagedObject
@end
#import "Location+CoreDataProperties.h"
これにより、元のクラスでカテゴリで指定されたプロパティを編集できます。
編集:警告:このプロパティは、クラスのすべてのインスタンスに対して一意の値を持ちます。
これは私にとってはうまくいきましたが、アプリにこのクラスのインスタンスが1つしかないためです。
#import <AVFoundation/AVFoundation.h>
@interface AVAudioPlayer (AstroAVAudioPlayer)
@property (nonatomic) BOOL redPilot;
@end
#import "AVAudioPlayer+AstroAVAudioPlayer.h"
@implementation AVAudioPlayer (AstroAVAudioPlayer)
BOOL _redPilot;
-(void) setRedPilot:(BOOL)redPilot
{
_redPilot = redPilot;
}
-(BOOL) redPilot
{
return _redPilot;
}
@end
これに対する解決策は、フラグを付けたい各オブジェクトに一意のタグを付けることでした。
すべてのラベルにカスタムフォントを追加するためにUILabelカテゴリを作成しましたが、一部では太字にしたいので、これを行いました->
- (void) layoutSubviews {
[super layoutSubviews];
[self addCustomFont];
}
- (void) addCustomFont {
if (self.tag == 22) {
[self setFont:[UIFont fontWithName:SEGOE_BOLD size:self.font.pointSize]];
}else{
[self setFont:[UIFont fontWithName:SEGOE_LIGHT size:self.font.pointSize]];
}
}