Размытый текст iOS: обнаружение и решение раз и навсегда?

Я неоднократно сталкивался с ситуацией, когда UIView (подкласс) заканчивается дробным смещением , например, потому что его размеры нечетные и он центрирован, или потому, что его местоположение основано на центре контейнера нечетного размера.

Это приводит к размытому тексту (или изображениям), потому что iOS будет пытаться визуализировать представление (и подпредставления) со смещением на полпикселя. Я считаю, что вызов CGRectIntegral () для каждой смены кадра не является идеальным решением.

Я ищу лучший способ легко обнаруживать такие ситуации. При написании этого вопроса я пришел к довольно радикальному подходу, который выявил в моем текущем проекте больше отклонений на 1/2, чем я мог себе представить.

Так что это для того, чтобы поделиться. Комментарии и предложения по лучшим или менее радикальным альтернативам более чем приветствуются.

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 должен быть установлен как флаг компилятора в режиме отладки.

5
задан mvds 9 January 2011 в 03:17
поделиться