2011-01-04 2 views
1

после WWDC2010 Сессия 104 Я только что создал CATiledLayer в пределах UIScrollView для изображения 10000 x 8078 пикселей.CATiledLayer получает неверное значение frame & contextCTM.a (zoomScale)

Я беспокойный с рамой & zoomScale, когда представление первых показывает на своем верхнем уровне

  1. как в сессии 104 я определил levelsOfDetail как 4
  2. в моей DrawRect я называю CGFloat lScale = CGContextGetCTM(lContext).a;

Странно во время выполнения lScale назначается 0.124907158, а не 0.125, как ожидалось.

Как хорошо rect передается drawRect имеет floatpoint значения, такие, как

  • rect.origin.x = 4099,04443
  • rect.origin.y = 6144
  • rect.size.width = 2049,52222
  • rect.size.height = 2048

Наиболее раздражающим для меня является то, что рама CATiledLayer показывает начало координат 0 x 26.93, хотя я создал tiledImageView, используя initWithFrame, используя начало 0x0.

Любые идеи, где я могу найти расчет, который несет ответственность за это?


РЕДАКТИРОВАТЬ: Я нашел источник для позиции кадра, странно, который граница Scrollview быть неправильно установлена ​​на 450 пикселей. это должно быть 420 пикселей. В процедуре layoutSubview в UIScrollView есть процедура просмотра по центру, которая непреднамеренно скорректировала координату y.

ответ

1

Я нашел лекарство от этого.

В примере 104 сеанса WWDC 2010 есть два метода UIScrollView, которые контролируют поведение представления.

Первый - configureForImageSize, о котором я упомянул в ранее опубликованном ответе, где установлены шкалы масштабирования.

Из-за объясненной разности точек с плавающей запятой границы изображения должны генерироваться с десятичными знаками, выделенными ранее (см. Wx/hx или wy/hy).

Чтобы очистить это я использовал переопределение layoutSubviews, где я вычислить вид кадра:

- (void) layoutSubviews { 
    [super layoutSubviews]; 

    CGSize lBoundsSize = self.bounds.size; 
    CGRect lFrameToCenter = imageView.frame; 

    // cure to the decimals problem 
    lFrameToCenter.size.width = roundf(lFrameToCenter.size.width); 
    lFrameToCenter.size.height = roundf(lFrameToCenter.size.height); 

    if (lFrameToCenter.size.width < lBoundsSize.width) 
     lFrameToCenter.origin.x = (lBoundsSize.width - lFrameToCenter.size.width)/2; 
    else 
     lFrameToCenter.origin.x = 0; 

    if (lFrameToCenter.size.height < lBoundsSize.height) 
     lFrameToCenter.origin.y = (lBoundsSize.height - lFrameToCenter.size.height)/2; 
    else 
     lFrameToCenter.origin.y = 0; 

    imageView.frame = lFrameToCenter; 

    if ([imageView isKindOfClass:[tileView class]]) { 
     imageView.contentScaleFactor = 1.0; 
    } 
} 

Обратите внимание, что я округлить размер кадра, прежде чем делать что-нибудь еще с ним!

+0

Вы только что исправили проблему, с которой я боролся часами. :-) У меня был CATiledLayer, который работал отлично, но когда я попытался изменить его положение (фрейм), значения шкалы внезапно изменились, например. 0,5-0,49756. Я пробовал ваше решение и округлял ширину и высоту CATiledLayer, и теперь он работает! Спасибо, что поделились решением, которое вы нашли. :-) –

+0

Хорошо, это действительно исправить проблему, но она представила другую. Когда вы хорошо масштабируетесь в UIScrollView, вы можете видеть, что размер CATiledLayer неверен в отношении UIScrollView. Вы можете видеть это, потому что правый и нижний края становятся черными, поскольку CATiledLayer не полностью заполняет UIScrollView, а затем вы можете увидеть цвет фона UIScrollView. В некоторых случаях это может быть хорошо, но, к сожалению, не в моем. Мне придется попробовать что-то еще, возможно, округлить масштаб. –

0

Я получил немного дальше в своем анализе ошибок.

Имея mImageSize из 10000x8078 и 320x450 Bounds в UIScrollView я использовал configureForImageSize расчеты из сеанса 104 например, следующим образом:

- (void) configureForImageSize:(CGSize)mImageSize { 
    CGSize lBoundsSize = [self bounds].size; 

    // set up our content size and min/max zoomscale 
    CGFloat lXScale = lBoundsSize.width/mImageSize.width; // the scale needed to perfectly fit the image width-wise 
    CGFloat lYScale = lBoundsSize.height/mImageSize.height; // the scale needed to perfectly fit the image height-wise 

    // debug values 
    float wx = mImageSize.width * lXScale; 
    float wy = mImageSize.width * lYScale; 
    float hx = mImageSize.height * lXScale; 
    float hy = mImageSize.height * lYScale; 

    ... 
} 

отладчик показывает следующие значения:

* mImageSize = width 10000 height 8078 
* bounds size: width 320 height 450 
* lXScale = 0.0396137647 
* lYScale = 0.0450000018 
* wx = 320 
* wy = 363.51001 
* hx = 396.137634 
* hy = 450.000031 

так Я вижу, что размер изображения по отношению к границам приводит к разнице в вычислениях с плавающей точкой. Когда генерируется CATiledLayer, границы всегда являются значениями с плавающей точкой.

Если это причина, как я могу получить математический выход из этого, не изменяя размер изображения (уродливое мышление) ???

+0

Даже после округления ширины и высоты до круглых чисел, я по-прежнему получаю странную шкалу от чего-то вроде 0.249921, в результате чего приложение не сможет найти соответствующие плитки. Как это исправить? – Matthew

Смежные вопросы