Fotoğraflar uygulaması gibi merkezli UIImageView ile UIScrollView

oy
37

Ben resim içerik görüntüsü kaydırma görünümünü istiyorum. görüntü aslında ekran çok daha büyük harita. Eğer yatay yönde iPhone açtığınızda harita Fotoğraflar uygulamasında fotoğrafları gibi, kaydırma görünümün merkezinde başlangıçta olmalıdır.

alt

Aynı anda doğru yakınlaştırma ve kaydırma ile merkezde harita başaramadı. harita resim (dikey yönde) ekranın üst kısmından başlar kaydıyla, kod şey gibi görünür:

- (void)loadView {
    mapView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@map.jpg]];
    CGFloat mapHeight = MAP_HEIGHT * SCREEN_WIDTH / MAP_WIDTH;
    mapView.frame = CGRectMake(0, 0, SCREEN_WIDTH, mapHeight);
    scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT)];
    scrollView.delegate = self;
    scrollView.contentSize = mapView.frame.size;
    scrollView.maximumZoomScale = MAP_WIDTH / SCREEN_WIDTH;
    scrollView.minimumZoomScale = 1;
    [scrollView addSubview:mapView];
    self.view = scrollView;
}

Ben merkeze görüntü karesini taşıdığınızda, görüntü çerçevesinden aşağı üstünden sadece yetişir. Dinamik imageview çerçevesini değişen, dönüşümü MapView uğraşmak çalıştı. Hiçbir şey şimdiye kadar benim için çalışıyor.

Oluştur 12/03/2009 saat 12:56
kaynak kullanıcı
Diğer dillerde...                            


11 cevaplar

oy
40

Bu kod iOS çoğu sürümlerinde çalışması gerekir (ve yukarı 3.1 üzerinde çalışmak için test edilmiştir).

Bu Yunus'un cevapta belirtildiği Apple WWDC koduna dayandırılmıştır.

UIScrollView sizin alt sınıf için aşağıdaki ekleyin ve imajınızı veya fayans içeren görüntüsü tileContainerView değiştirin:

- (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;
}
Cevap 13/08/2010 saat 17:42
kaynak kullanıcı

oy
23

İşte elma fotoğraf uygulaması gibi tam davranır gibi ben, çözümü düşünün budur. Kullandığım çözümlerini kullanarak olmuştu:

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

recenter ama yakınlaştırma bittikten sonra, o zaman çok un-seksi merkezine hızlı 'atlama' sıçrama ediyorum çünkü bu çözüm sevmedim için. hemen hemen ama bu temsilci işlevinde aynı mantık yaparsanız çıkıyor:

-(void)scrollViewDidZoom:(UIScrollView *)pScrollView

her iki merkezli kapalı başlar ve uzaklaştırmak zaman kalır merkezli:

-(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;
}

Nerede 'imageview' dir UIImageViewkullandığınız.

Cevap 03/02/2010 saat 03:51
kaynak kullanıcı

oy
7

Elma iPhone geliştirici programının tüm üyelerine 2010 WWDC oturumu videoları yayınladı. tartışılan konulardan biri de resmi uygulaması oluşturulur nasıl !!! Onlar adım çok benzer bir uygulama aşamasını oluşturmak ve ücretsiz olarak tüm kodu kullanılabilir hale getirmiştir.

Ya özel api kullanmaz. Çünkü sigara gizlilik anlaşması burada kodun herhangi koymak, ama burada örnek kod indirmek için bir bağlantı olamaz. Muhtemelen erişebilmek için giriş yapmanız gerekecek.

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

Ve burada iTunes WWDC sayfasına bir link:

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

Cevap 20/06/2010 saat 20:48
kaynak kullanıcı

oy
2

Sana ayarlamanız gerekir şüpheli UIScrollView's contentOffset.

Cevap 12/03/2009 saat 20:16
kaynak kullanıcı

oy
1

Bu benim için çalıştı:

- (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 senin yarısı genişlik / yükseklik olduğu UIScrollView.

Ardından daha sonra burada yakalanan birine contentoffset ayarlayın.

Cevap 31/03/2009 saat 09:15
kaynak kullanıcı

oy
1

Ben bu kadar basit olsaydı. Ben net biraz araştırma yaptım ve bu sadece benim sorunum değil, ancak birçok kişi de iPhone'da ancak Apple'ın masaüstü Kakao değil sadece aynı sorunu ile mücadele ortaya koydu. Aşağıdaki bağlantılara bakın:

http://www.iphonedevsdk.com/forum/iphone-sdk-development/5740-uiimageview-uiscrollview.html
açıklanan çözüm görüntüsünün mülkiyet UIViewContentModeScaleAspectFit dayanmaktadır ancak maalesef çok iyi .bir görüntüdür çalışmıyor merkezli ve düzgün büyür, ama sıçrayan alan resim çok daha büyük görünüyor.

Bu adam cevap alamadım ya:
http://discussions.apple.com/thread.jspa?messageID=8322675

Ve son olarak, Apple'ın masaüstü Kakao aynı sorun:
http://www.cocoadev.com/index.pl?CenteringInsideNSScrollView
Ben çözüm çalışır herhalde, ancak iPhone'da değil NSClipView dayanmaktadır ...

Herkes iPhone'da çalışan bazı çözümü var?

Cevap 13/03/2009 saat 08:29
kaynak kullanıcı

oy
0

İşte JosephH cevabı @ benzer alternatif bir çözüm, ama bu bir hesaba görüntünün gerçek boyutlarını alır. Kullanıcı tava / yakınlaştırır, sen gerekenden daha ekranda daha fazla boşluk asla zaman diye. Bir portre ekranda bir manzara görüntüsünü gösterirken Bu, örneğin ortak bir sorundur. tüm görüntü ekranına (Aspect Fit) açıkken boşluk üstünde ve resmin altında olacak burada. yakınlaştırma zaman imageview içerisinde olması dolayısıyla Ardından, diğer çözümler, görüntünün bir parçası olarak bu boşluk düşünün. Onlar sadece boşluk görünür bırakarak ekran kapalı görüntünün çoğunluğunu kaydırmak izin verir. Bu kullanıcı için kötü görünüyor.

Bu sınıfa ile, bunu onunla çalışıyor imageView geçmesi gerekiyor. Ben otomatik olarak algılayacak için cazip, ama bu daha hızlıdır ve size olsun tüm hızı istediğiniz layoutSubviewsyöntemle.

Not: olduğu gibi bu AutoLayout scrollview için etkin olmadığını gerektirir.

//
//  CentringScrollView.swift
//  Cerebral Gardens
//
//  Created by Dave Wood
//  Copyright © 2016 Cerebral Gardens Inc. All rights reserved.
//

import UIKit

class CentringScrollView: UIScrollView {

    var imageView: UIImageView?

    override func layoutSubviews() {
        super.layoutSubviews()

        guard let superview = superview else { return }
        guard let imageView = imageView else { return }
        guard let image = imageView.image else { return }

        var frameToCentre = imageView.frame

        let imageWidth = image.size.width
        let imageHeight = image.size.height

        let widthRatio = superview.bounds.size.width / imageWidth
        let heightRatio = superview.bounds.size.height / imageHeight

        let minRatio = min(widthRatio, heightRatio, 1.0)

        let effectiveImageWidth = minRatio * imageWidth * zoomScale
        let effectiveImageHeight = minRatio * imageHeight * zoomScale

        contentSize = CGSize(width: max(effectiveImageWidth, bounds.size.width), height: max(effectiveImageHeight, bounds.size.height))

        frameToCentre.origin.x = (contentSize.width - frameToCentre.size.width) / 2
        frameToCentre.origin.y = (contentSize.height - frameToCentre.size.height) / 2

        imageView.frame = frameToCentre
    }
}
Cevap 05/05/2016 saat 09:56
kaynak kullanıcı

oy
0

MonoTouch benim için çalıştı.

this._scroll.ScrollRectToVisible(new RectangleF(_scroll.ContentSize.Width/2, _scroll.ContentSize.Height/2,1,1),false);
Cevap 08/08/2012 saat 15:45
kaynak kullanıcı

oy
0

Içeriğini ortalamak için zarif bir yolu, UISCrollViewbudur.

Bir gözlemci ekle contentSize aramalarınızdan UIScrollView, bu nedenle bu yöntem her içerik değişikliği adı verilecek ...

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

Şimdi gözlemci yöntemi:

- (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 ); }
  • Sen değişmelidir [pointer viewWithTag:100]. Içerik görünümü tarafından değiştirin UIView.

    • Ayrıca değiştirmek imageGalleryiçin pencere boyutuna işaret.

Bu içerik her şey onun boyut değişikliği merkezini düzeltecektir.

NOT: Bu içeriği çok iyi çalışıyor yok tek yolu standart zoom işlevi olduğunu UIScrollView.

Cevap 03/11/2009 saat 18:14
kaynak kullanıcı

oy
0

Tamam, ben bu soruna oldukça iyi bir çözüm buldum. hüner sürekli ImageView'ın çerçevesini yeniden ayarlamak etmektir. Bu sürekli contentInsets veya contentOffSets ayarlayarak çok daha iyi sonuç verdi. Ben hem dikey hem de yatay görüntüleri karşılamak için ekstra kod biraz eklemek zorunda kaldı.

İşte kod:

- (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];
}
Cevap 04/10/2009 saat 03:16
kaynak kullanıcı

oy
0

Not: çalışmaların bu yöntem tür. görüntü ImageView küçükse, bu ekranın dışına kısmen kayar. Büyük bir anlaşma değil, ama fotoğraflar uygulaması olarak da güzel değildi.

Birincisi, biz 2 görünümleri, içinde görüntü ile ImageView ve içinde ImageView ile Scrollview ile ilgili olduğunu anlamak önemlidir. Yani, ilk ekran boyutuna ImageView ayarlayın:

 [myImageView setFrame:self.view.frame];

Ardından, ImageView içinde imajınızı ortalamak:

 myImageView.contentMode = UIViewContentModeCenter;

İşte benim bütün kodu:

- (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];
 }
Cevap 08/09/2009 saat 03:14
kaynak kullanıcı

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more