5

UIView (サブクラス) が分数オフセットになる状況に何度も遭遇しました。たとえば、その寸法が奇数で中央に配置されているため、またはその位置が奇数サイズのコンテナーの中心に基づいているためです。

これにより、テキスト (または画像) がぼやけます。これは、iOS が半ピクセル オフセットでビュー (およびサブビュー) をレンダリングしようとするためです。CGRectIntegral()すべてのフレーム変更を要求することは、完全な解決策ではないと感じています。

これらの状況を簡単に検出するための最良の方法を探しています。この質問を書いているときに、私は非常に抜本的なアプローチを思いつきました。これにより、現在のプロジェクトで、想像以上に ½ ずつずれていることが明らかになりました。

これは共有用です。より良い、またはあまり抜本的でない代替案についてのコメントや提案は大歓迎です。

main.m

#import <objc/runtime.h>
#import "UIViewOverride.h"

int main(int argc, char *argv[]) {

#ifdef DEBUGVIEW
    Method m1,m2;
    IMP imp;
    m1 = class_getInstanceMethod([UIView class], @selector(setFrame:));
    m2 = class_getInstanceMethod([UIViewOverride class], @selector(setFrameOverride:));
    imp = method_getImplementation(m2);
    class_addMethod([UIView class], @selector(setFrameOverride:), imp, method_getTypeEncoding(m1));
    m2 = class_getInstanceMethod([UIView class], @selector(setFrameOverride:));
    method_exchangeImplementations(m1,m2);

    m1 = class_getInstanceMethod([UIView class], @selector(setCenter:));
    m2 = class_getInstanceMethod([UIViewOverride class], @selector(setCenterOverride:));
    imp = method_getImplementation(m2);
    class_addMethod([UIView class], @selector(setCenterOverride:), imp, method_getTypeEncoding(m1));
    m2 = class_getInstanceMethod([UIView class], @selector(setCenterOverride:));
    method_exchangeImplementations(m1,m2);
#endif

// etc

UIViewOverride.m

これは UIView サブクラスとして実装され、キャストやコンパイラの警告を回避します。

#define FRACTIONAL(f) (fabs(f)-floor(fabs(f))>0.01)

@implementation UIViewOverride

#ifdef DEBUGVIEW
-(void)setFrameOverride:(CGRect)newframe
{
    if ( FRACTIONAL(newframe.origin.x) || FRACTIONAL(newframe.origin.y) )
    {
        [self setBackgroundColor:[UIColor redColor]];
        [self setAlpha:0.2];
        NSLog(@"fractional offset for %@",self);
    }
    [self setFrameOverride:newframe]; // not a typo
}

-(void)setCenterOverride:(CGPoint)center
{
    [self setCenterOverride:center]; // not a typo
    if ( FRACTIONAL(self.frame.origin.x) || FRACTIONAL(self.frame.origin.y) )
    {
        [self setBackgroundColor:[UIColor greenColor]];
        [self setAlpha:0.2];
        NSLog(@"fractional via center for %@",self);
    }
}
#endif

問題のあるビューでは、ログ メッセージが生成され、透明になり、赤または緑になります。

-DDEBUGVIEWデバッグ モードでコンパイラ フラグとして設定されます。

4

1 に答える 1

8

これと同じ機能は、CoreAnimation インストゥルメントとその不整列フラグを介して取得できます。

于 2011-01-09T03:33:14.133 に答える