UIScrollView с UIImageView в центре, как фото приложение

Похоже, что это атрибут директивы страницы isThreadSafe. Когда я изменяю его с false на true, страницы отображаются в нескольких браузерах одновременно.

37
задан Community 8 February 2017 в 14:10
поделиться

9 ответов

Мне жаль, что это не было настолько просто. Я провел некоторое исследование в сети и нашел, что это не просто моя проблема, но и многие люди борются с той же проблемой не только на iPhone, но и на настольном Какао Apple также. Посмотрите следующие ссылки:

http://www.iphonedevsdk.com/forum/iphone-sdk-development/5740-uiimageview-uiscrollview.html
описанное решение основано на свойстве UIViewContentModeScaleAspectFit изображения, но к сожалению оно не работает очень хорошо.The, изображение центрируется и растет правильно, но возвращаемая область, кажется, намного больше, чем изображение.

Этот парень не получил ответ также:
http://discussions.apple.com/thread.jspa?messageID=8322675

И наконец, та же проблема на настольном Какао Apple:
http://www.cocoadev.com/index.pl?CenteringInsideNSScrollView
я предполагаю работы решения, но это основано на NSClipView, который не находится на iPhone...

у Кого-либо есть некоторое решение, работающее над iPhone?

1
ответ дан Martin Ludvik 27 November 2019 в 04:34
поделиться

Я подозреваю, что необходимо установить UIScrollView contentOffset.

2
ответ дан etolstoy 27 November 2019 в 04:34
поделиться

Это работало на меня:

- (void) scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale {
CGFloat tempx = view.center.x-160;
CGFloat tempy = view.center.y-160;
myScrollViewOffset = CGPointMake(tempx,tempy);

}

где 160 половина ширины/высоты Вашего UIScrollView.

Затем позже я установил contentoffset на тот, полученный здесь.

1
ответ дан etolstoy 27 November 2019 в 04:34
поделиться

Примечание: этот метод сортирует работ. если изображение меньше, чем imageView, оно будет частично прокручиваться за пределы экрана. Ничего особенного, но и не такое приятное, как приложение для фотографий.

Во-первых, важно понимать, что мы имеем дело с двумя видами: просмотр изображения с изображением в нем и просмотр прокрутки с просмотром изображения в нем. Итак, сначала установите размер изображения в соответствии с размером экрана:

 [myImageView setFrame:self.view.frame];

Затем отцентрируйте изображение в окне просмотра изображения:

 myImageView.contentMode = UIViewContentModeCenter;

Вот мой полный код:

- (void)viewDidLoad {
AppDelegate *appDelegate = (pAppDelegate *)[[UIApplication sharedApplication] delegate];
 [super viewDidLoad];
 NSString *Path = [[NSBundle mainBundle] bundlePath];
 NSString *ImagePath = [Path stringByAppendingPathComponent:(@"data: %@", appDelegate.MainImageName)];
 UIImage *tempImg = [[UIImage alloc] initWithContentsOfFile:ImagePath];
 [imgView setImage:tempImg];

 myScrollView = [[UIScrollView alloc] initWithFrame:[[self view] bounds]];
 [myScrollView addSubview:myImageView];

//Set ScrollView Appearance
 [myScrollView setBackgroundColor:[UIColor blackColor]];
 myScrollView.indicatorStyle = UIScrollViewIndicatorStyleWhite;

//Set Scrolling Prefs
 myScrollView.bounces = YES;
 myScrollView.delegate = self;
 myScrollView.clipsToBounds = YES; // default is NO, we want to restrict drawing within our scrollview
 [myScrollView setCanCancelContentTouches:NO];
 [myScrollView setScrollEnabled:YES];


//Set Zooming Prefs
 myScrollView.maximumZoomScale = 3.0;
 myScrollView.minimumZoomScale = CGImageGetWidth(tempImg.CGImage)/320;
 myScrollView.zoomScale = 1.01; //Added the .01 to enable scrolling immediately upon view load.
 myScrollView.bouncesZoom = YES;


 [myImageView setFrame:self.view.frame];//rect];// .frame.size.height = imageHeight;
 myImageView.contentMode = UIViewContentModeCenter;
 self.view = myScrollView;
 [tempImg release];
 }
0
ответ дан 27 November 2019 в 04:34
поделиться

Хорошо, я думаю Я нашел довольно хорошее решение этой проблемы. Уловка состоит в том, чтобы постоянно корректировать рамку imageView. Я считаю, что это работает намного лучше, чем постоянно корректировать contentInsets или contentOffSets. Мне пришлось добавить немного дополнительного кода для работы с портретными и альбомными изображениями.

Вот код:

- (void) scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale {

CGSize screenSize = [[self view] bounds].size;

if (myScrollView.zoomScale <= initialZoom +0.01) //This resolves a problem with the code not working correctly when zooming all the way out.
{
    imageView.frame = [[self view] bounds];
    [myScrollView setZoomScale:myScrollView.zoomScale +0.01];
}

if (myScrollView.zoomScale > initialZoom)
{
    if (CGImageGetWidth(temporaryImage.CGImage) > CGImageGetHeight(temporaryImage.CGImage)) //If the image is wider than tall, do the following...
    {
            if (screenSize.height >= CGImageGetHeight(temporaryImage.CGImage) * [myScrollView zoomScale]) //If the height of the screen is greater than the zoomed height of the image do the following...
            {
                    imageView.frame = CGRectMake(0, 0, 320*(myScrollView.zoomScale), 368);
            }
            if (screenSize.height < CGImageGetHeight(temporaryImage.CGImage) * [myScrollView zoomScale]) //If the height of the screen is less than the zoomed height of the image do the following...
            {
                    imageView.frame = CGRectMake(0, 0, 320*(myScrollView.zoomScale), CGImageGetHeight(temporaryImage.CGImage) * [myScrollView zoomScale]);
            }
    }
    if (CGImageGetWidth(temporaryImage.CGImage) < CGImageGetHeight(temporaryImage.CGImage)) //If the image is taller than wide, do the following...
    {
            CGFloat portraitHeight;
            if (CGImageGetHeight(temporaryImage.CGImage) * [myScrollView zoomScale] < 368)
            { portraitHeight = 368;}
            else {portraitHeight = CGImageGetHeight(temporaryImage.CGImage) * [myScrollView zoomScale];}

            if (screenSize.width >= CGImageGetWidth(temporaryImage.CGImage) * [myScrollView zoomScale]) //If the width of the screen is greater than the zoomed width of the image do the following...
            {
                    imageView.frame = CGRectMake(0, 0, 320, portraitHeight);
            }
            if (screenSize.width < CGImageGetWidth (temporaryImage.CGImage) * [myScrollView zoomScale]) //If the width of the screen is less than the zoomed width of the image do the following...
            {
                    imageView.frame = CGRectMake(0, 0, CGImageGetWidth(temporaryImage.CGImage) * [myScrollView zoomScale], portraitHeight);
            }
    }
    [myScrollView setZoomScale:myScrollView.zoomScale -0.01];
}
0
ответ дан 27 November 2019 в 04:34
поделиться

One elegant way to center the content of UISCrollView is this.

Add one observer to the contentSize of your UIScrollView, so this method will be called everytime the content change...

[myScrollView addObserver:delegate 
               forKeyPath:@"contentSize"
                  options:(NSKeyValueObservingOptionNew) 
                  context:NULL];

Now on your observer method:

- (void)observeValueForKeyPath:(NSString *)keyPath   ofObject:(id)object   change:(NSDictionary *)change   context:(void *)context { 

    // Correct Object Class.
    UIScrollView *pointer = object;

    // Calculate Center.
    CGFloat topCorrect = ([pointer bounds].size.height - [pointer viewWithTag:100].bounds.size.height * [pointer zoomScale])  / 2.0 ;
            topCorrect = ( topCorrect < 0.0 ? 0.0 : topCorrect );

    topCorrect = topCorrect - (  pointer.frame.origin.y - imageGallery.frame.origin.y );

    // Apply Correct Center.
    pointer.center = CGPointMake(pointer.center.x,
                                 pointer.center.y + topCorrect ); }
  • You should change the [pointer viewWithTag:100]. Replace by your content view UIView.

    • Also change imageGallery pointing to your window size.

This will correct the center of the content everytime his size change.

NOTE: The only way this content don't works very well is with standard zoom functionality of the UIScrollView.

0
ответ дан 27 November 2019 в 04:34
поделиться

JavaScript является однопоточным. Поэтому по определению вы не можете обновлять пользовательский интерфейс, пока находитесь в цикле прилива. Однако начиная с Firefox 3.5 добавлена поддержка многопоточных JavaScripts, называемых веб-работниками. Веб-работники не могут влиять на пользовательский интерфейс страницы, но и не блокируют обновления пользовательского интерфейса. Нас также поддерживают Chrome и Safari.
Проблема в том, что даже если переместить вызов AJAX в фоновый поток и дождаться завершения выполнения, пользователи смогут нажимать кнопки и изменять значения в пользовательском интерфейсе (и, насколько я понимаю, этого вы пытаетесь избежать). Единственное, что я могу предложить, чтобы предотвратить пользователей за какие-либо изменения, это вращатель, который будет блокировать весь пользовательский интерфейс и не будет позволять никакого взаимодействия со страницей, пока веб-вызов не вернется.

-121--4481972-

Часть причины состоит в том, что вы получите исключения нулевого указателя слева и справа. Отправка сообщения в nil разрешена и часто совершенно законна (она ничего не делает и не порождает ошибки).

Но вы можете считать, что это аналогично нотации C++ - > : Она выполняет метод и удаляет указатель в одном фрагменте синтаксического сахара.

-121--1080964-

Вот что я бы подумал, решение, как в нем ведет себя в точности как яблоко фото app. Я использовал решения, которые использовали:

-(void) scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale

для повторного входа, но мне не понравилось это решение, потому что после увеличения было сделано, он отскочит, а затем быстро «прыгнуть» в центр, который был очень сексуальный. Оказывается, если вы в значительной степени делаете ту же самую логику, но в этой функции делегата:

-(void)scrollViewDidZoom:(UIScrollView *)pScrollView

она как начинается по центру, так и при уменьшении масштаба остается по центру:

-(void)scrollViewDidZoom:(UIScrollView *)pScrollView {
CGRect innerFrame = imageView.frame;
CGRect scrollerBounds = pScrollView.bounds;

if ( ( innerFrame.size.width < scrollerBounds.size.width ) || ( innerFrame.size.height < scrollerBounds.size.height ) )
{
    CGFloat tempx = imageView.center.x - ( scrollerBounds.size.width / 2 );
    CGFloat tempy = imageView.center.y - ( scrollerBounds.size.height / 2 );
    CGPoint myScrollViewOffset = CGPointMake( tempx, tempy);

    pScrollView.contentOffset = myScrollViewOffset;

}

UIEdgeInsets anEdgeInset = { 0, 0, 0, 0};
if ( scrollerBounds.size.width > innerFrame.size.width )
{
    anEdgeInset.left = (scrollerBounds.size.width - innerFrame.size.width) / 2;
    anEdgeInset.right = -anEdgeInset.left;  // I don't know why this needs to be negative, but that's what works
}
if ( scrollerBounds.size.height > innerFrame.size.height )
{
    anEdgeInset.top = (scrollerBounds.size.height - innerFrame.size.height) / 2;
    anEdgeInset.bottom = -anEdgeInset.top;  // I don't know why this needs to be negative, but that's what works
}
pScrollView.contentInset = anEdgeInset;
}

Где 'imageView' является UIImageView вы используете.

23
ответ дан 27 November 2019 в 04:34
поделиться

Apple выпустила видеоролики сеанса WWDC 2010 для всех участников программы для разработчиков iphone. Одна из обсуждаемых тем - как они создали приложение для фотографий !!! Они шаг за шагом создают очень похожее приложение и сделали весь код доступным бесплатно.

Он также не использует частный API. Я не могу поместить сюда какой-либо код из-за соглашения о неразглашении, но вот ссылка на загрузку образца кода. Вам, вероятно, потребуется войти в систему, чтобы получить доступ.

http://connect.apple.com/cgi-bin/WebObjects/MemberSite.woa/wa/getSoftware?code=y&source=x&bundleID=20645

И вот ссылка на страницу iTunes WWDC:

http://insideapple.apple.com/redir/cbx-cgi.do?v=2&la=en&lc=&a=kGSol9sgPHP%2BtlWtLp%2BEP%2FnxnZarjWJglPBZRHd3oDbACudP51JNGS8KlsFgxZto9X%2BTsnqSbeUSWX0doe%2Fzv%2FN5XV55%2FomsyfRgFBysOnIVggO%2Fn2p%2BiweDK%2F% 2FmsIXj

7
ответ дан 27 November 2019 в 04:34
поделиться

Этот код должен работать в большинстве версий iOS (и был протестирован для работы в версиях 3.1 и выше).

Он основан на коде Apple WWDC, упомянутом в ответе Ионы.

Добавьте приведенный ниже код в свой подкласс UIScrollView и замените tileContainerView представлением, содержащим ваше изображение или плитки:

- (void)layoutSubviews {
    [super layoutSubviews];

    // center the image as it becomes smaller than the size of the screen
    CGSize boundsSize = self.bounds.size;
    CGRect frameToCenter = tileContainerView.frame;

    // center horizontally
    if (frameToCenter.size.width < boundsSize.width)
        frameToCenter.origin.x = (boundsSize.width - frameToCenter.size.width) / 2;
    else
        frameToCenter.origin.x = 0;

    // center vertically
    if (frameToCenter.size.height < boundsSize.height)
        frameToCenter.origin.y = (boundsSize.height - frameToCenter.size.height) / 2;
    else
        frameToCenter.origin.y = 0;

    tileContainerView.frame = frameToCenter;
}
40
ответ дан 27 November 2019 в 04:34
поделиться