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
デバッグ モードでコンパイラ フラグとして設定されます。