2016-08-10 5 views
1

問題があります。第三者libのframe.size.widthを変更できません。幅を変更するための通常の解決策が見つかりませんでしたので、私はobjc/runtimeを実行することにしました。Objective-C初期化されたオブジェクトの実行時に変更されるreadonlyプロパティ

私はViewControllerとそのプロパティを持っていますDTAttributedTextView * v。

@interface DTAttributedTextView : UIScrollView 
{ 
// ivars needed by subclasses 
DTAttributedTextContentView *_attributedTextContentView; 
} 

@property (nonatomic, strong) NSAttributedString *attributedString; 
@property (nonatomic, DT_WEAK_PROPERTY) IBOutlet 
id<DTAttributedTextContentViewDelegate> textDelegate; 
@property (nonatomic, strong) IBOutlet UIView *backgroundView; 
.... 
@end 

vが@property(..、読み取り専用)DTAttributedTextContentView * attributedTextContentView

@interface DTAttributedTextContentView : UIView 
{ 
     NSAttributedString *_attributedString; 
     DTCoreTextLayoutFrame *_layoutFrame; 

     UIEdgeInsets _edgeInsets; 

     NSMutableDictionary *customViewsForAttachmentsIndex; 

     BOOL _flexibleHeight; 

     // for layoutFrame 
     NSInteger _numberOfLines; 
     NSLineBreakMode _lineBreakMode; 
     NSAttributedString *_truncationString; 
} 

attributedTextContentViewだから基本的に私がする必要がある@property DTCoreTextLayoutFrame * layoutFrame

@interface DTCoreTextLayoutFrame : NSObject 
{ 
    CGRect _frame; 

    NSArray *_lines; 
    NSArray *_paragraphRanges; 

    NSArray *_textAttachments; 
    NSAttributedString *_attributedStringFragment; 
} 

を得ました変更

私は、ドット表記法によるアイバーズにアクセスし、また&場合CGFloat必要なイベントとしてCGStructを送信することはできませんので、私は

objc_setAssociatedObject(self.v.attributedTextContentView.layoutFrame,@"frame.size.width",@200,OBJC_ASSOCIATION_ASSIGN); 

objc_setAssociatedObject(self.v.attributedTextContentView.layoutFrame,@"frame",CGRectMake(0,0,200,1000),OBJC_ASSOCIATION_ASSIGN); 

を使用するカントピティーため

self.v.attributedTextContentView.layoutFrame.frame.size.width 

この状況の別の解決策として、私は実行時にオブジェクトを使ってオブジェクトを作成してからポインタを変更する方法を見ています。コピーを使用していくつかのステップを実行できます。 私の問題は、objc/runtimeのim new tieですし、ドキュメントも実際には貧弱です。 Imはこの重要な技術を学ぶのに苦労しているので、私は意図的に他のオプションを使って正確な問題を解決していません。

ご協力いただければ幸いです。 Thanxは事前に

+0

私はスタンドアートオブジェクトの作成を使用してフレームで元の問題を解決しました。しかし、動的な値の変更のためにランタイムを使用することは、現実のままです。 – KysokZla

答えて

0

あなたが間違っ代をやっているようですが、あなたは本当に別のインスタンスのIVAR(これは予期しない動作につながる可能性)に値を設定する必要がある場合、これはあなたが知っておくべきである:

1)関連するオブジェクトあなたはそれが

2プロパティ/ IVARの値は変更されません同じプロパティ/ IVAR名というキーに関連付けられたオブジェクトを追加しますので、もしあなたがcannot change the part of structureこの構造はオブジェクト

の財産である、それならば)、インスタンスの一部ではありません

3)電話番号valueForKey:/でivarsにアクセスできますaccessInstanceVariablesDirectlyプロパティがオーバーライドされていない場合はです。

4)あなたはとても、結果コードは次のようになります。setValue:forKey:

に渡す前にwrap your structure to NSValueする必要があります。KVCの詳細については、Key-Value Coding Programming Guideをチェック

DTCoreTextLayoutFrame *layoutFrame = self.v.attributedTextContentView.layoutFrame; 
CGRect frame = [[layoutFrame valueForKey:@"_frame"] CGRectValue]; 
frame.size.width = 200.0; 
NSValue* frameValue = [NSValue valueWithCGRect:frame]; 
[layoutFrame setValue:frameValue forKey:@"_frame"]; 

更新:

あなたはランタイム関数を使用したい場合は、あなたがする必要があります。

1))

2(すべてのObjective-Cのオブジェクトは、構造体である)インスタンス変数のオフセットを取得あなたが興味を持っているivarへのポインタを作成する

3)このポインタから直接読み書きする

これはコードです

DTCoreTextLayoutFrame *layoutFrame = self.v.attributedTextContentView.layoutFrame;  
Ivar ivar = class_getInstanceVariable([DTCoreTextLayoutFrame class], "_frame"); 
ptrdiff_t offset = ivar_getOffset(ivar); 
CGRect *framePtr = (__bridge void*)layoutFrame + offset; 
CGRect frame = *framePtr; 
frame.size.width = 100; 
*framePtr = frame; 
+0

Yeap、thanx私はすべてのオブジェクトを1つずつinsting同じアプローチを使用して解決しましたが、私の質問は、実行時関数を使用してこの問題を解決する方法はまだ実際です。 – KysokZla

+0

実際、私は解決策でオブジェクト(NSValue - CGRectラッパーを除く)を作成しません。しかし、私は、ランタイム関数を使用するアプローチを追加しました。 –

関連する問題