UIScrollView a középre UIImageView, mint Fotók alkalmazás

szavazat
37

Azt szeretném, hogy a scroll nézet egy képtartalom kilátás. A kép valójában térkép, ami sokkal nagyobb, mint a képernyőn. A térkép legyen kezdetben a központban a tekercset véli, mint a fotók Fotók alkalmazás, ha viszont iPhone fekvő tájolású.

alt

Nem sikerült, hogy a térkép közepén helyes nagyítás és görgetés egyidejűleg. Feltéve, hogy a térkép kép indul a képernyő tetején (álló helyzetben), a kód így néz ki:

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

Amikor mozog a kép keret a központtól, a kép nő csak a tetején a keret le. Próbáltam játszani körül mapView átalakítani, dinamikusan változó képkocka a Kamerák. Semmi sem működik nekem eddig.

A kérdést 12/03/2009 12:56
a forrás felhasználó
Más nyelveken...                            


11 válasz

szavazat
40

Ez a kód működik a legtöbb változata iOS (és tesztelték a munkát 3.1-től felfelé).

Ez alapján az Apple WWDC említett kód Jonah választ.

Adjuk hozzá a lenti az alosztálya UIScrollView, és cserélje tileContainerView azzal a nézettel, amely a kép vagy csempe:

- (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;
}
Válaszolt 13/08/2010 17:42
a forrás felhasználó

szavazat
23

Itt van, amit én úgy az oldat, mint ez pontosan úgy viselkedik, mint az Apple Photo alkalmazás. Én már a megoldás, hogy használni:

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

hogy centrikus, de nem tettem, mint ez a megoldás, mert miután a zoom-ben történik meg, akkor azt ugrál majd gyors „ugrani” a központ, amely nagyon un-szexi. Kiderült, ha elég sok nem pontosan ugyanaz a logika, de ebben az megbízottja funkció:

-(void)scrollViewDidZoom:(UIScrollView *)pScrollView

ez mind indul középre, és ha kicsinyítés akkor marad középen:

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

Ahol „Kamerák” a UIImageView'használ.

Válaszolt 03/02/2010 03:51
a forrás felhasználó

szavazat
7

Az Apple kiadta a 2010-es WWDC ülésen videók minden tagja az iPhone fejlesztői program. Az egyik témája, hogy hogyan hoztak létre a fotók app !!! Építettek egy nagyon hasonló app lépésről lépésre, és tettek összes kódot ingyenesen elérhető.

Ez nem használ saját api sem. Nem tudom tenni a kódokat itt, mert a titoktartási megállapodást, de itt egy link, hogy a minta kódot letölthető. Valószínűleg kell jelentkezned, hogy hozzáférjen.

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

És itt van egy link az iTunes WWDC oldalon:

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

Válaszolt 20/06/2010 20:48
a forrás felhasználó

szavazat
2

Gyanítom, hogy meg kell állítani a UIScrollView„s contentOffset.

Válaszolt 12/03/2009 20:16
a forrás felhasználó

szavazat
1

Ez nekem dolgozott:

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

}

ahol 160 fele szélesség / magasság a UIScrollView.

Aztán később meg a contentoffset az egyik elfogott itt.

Válaszolt 31/03/2009 09:15
a forrás felhasználó

szavazat
1

Bárcsak ilyen egyszerű lenne. Utánanéztem a neten, és úgy találta, hogy ez nem csak az én problémám, de sok ember küzd ugyanazzal a kérdéssel nem csak az iPhone, de az Apple asztali Cocoa is. Lásd az alábbi linkeket:

http://www.iphonedevsdk.com/forum/iphone-sdk-development/5740-uiimageview-uiscrollview.html
Az ismertetett megoldás alapja az ingatlan UIViewContentModeScaleAspectFit a kép, de sajnos ez nem működik jól .A kép központú és növekszik rendesen, de a pattogó területen úgy tűnik, hogy sokkal nagyobb, mint a képen.

Ez a fickó nem kap választ vagy:
http://discussions.apple.com/thread.jspa?messageID=8322675

És végül, ugyanaz a probléma az Apple asztali Kakaó:
http://www.cocoadev.com/index.pl?CenteringInsideNSScrollView
Gondolom, a megoldás működik, de ez alapján a NSClipView, ami nem az iPhone-on ...

Bárki van néhány megoldás dolgozik iPhone?

Válaszolt 13/03/2009 08:29
a forrás felhasználó

szavazat
0

Íme egy alternatív megoldás, hasonlóan @ JosephH válasza, de ez figyelembe veszi a tényleges méreteit a kép. Tehát, hogy ha a felhasználó edények / zoomok, akkor nem kell több szóközt a képernyőn, mint szükséges. Ez egy gyakori probléma, például akkor, amikor bemutatja a táj kép egy portré képernyőn. Ott lesz szóköz felett és alatt a képet, amikor a teljes kép a képernyőn (Aspect Fit). Aztán, amikor nagyítás, a többi megoldás úgy vélik, hogy a whitespace, mint a kép egy részét, mert a Kamerák. Ezek segítségével mozgathatja a legtöbb kép ki a képernyőt, így csak a szóközöket látható. Ez úgy néz ki rosszul a felhasználó számára.

Az ebbe az osztályba, ha nem kell, hogy adja át a Kamerák ez dolgozik. Nagy volt a kísértés, hogy azt automatikusan érzékeli, de ez gyorsabb, és azt akarjuk, a sebesség lehet kapni a layoutSubviewsmódszert.

Megjegyzés: Amint az szükséges, hogy Elrendezés nincs engedélyezve a scrollView.

//
//  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
    }
}
Válaszolt 05/05/2016 09:56
a forrás felhasználó

szavazat
0

A MonoTouch hogy nekem dolgozott.

this._scroll.ScrollRectToVisible(new RectangleF(_scroll.ContentSize.Width/2, _scroll.ContentSize.Height/2,1,1),false);
Válaszolt 08/08/2012 15:45
a forrás felhasználó

szavazat
0

Egy elegáns módja a központtól tartalmát UISCrollViewez.

Adjunk hozzá egy megfigyelőt a contentSize az UIScrollView, így ez a módszer lesz az úgynevezett everytime tartalmi változás ...

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

Most a megfigyelő mód:

- (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 ); }
  • Meg kell változtatni a [pointer viewWithTag:100]. Cserélje által a tartalom nézet UIView.

    • Szintén változik imageGallerymutatva az ablak méretét.

Ez korrigálja a központ a tartalom minden alkalommal ő mérete változás.

Megjegyzés: Az egyetlen módja a tartalom nem nagyon jól működik a standard zoom funkció a UIScrollView.

Válaszolt 03/11/2009 18:14
a forrás felhasználó

szavazat
0

Oké, azt hiszem, találtam egy nagyon jó megoldás erre a problémára. A trükk az, hogy folyamatosan be újra a Kamerák a keretben. Szerintem ez sokkal jobban működik, mint a folyamatosan kiigazítására contentInsets vagy contentOffSets. Kellett hozzá egy kis extra kód elhelyezésére álló és fekvő képek.

Itt a kód:

- (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];
}
Válaszolt 04/10/2009 03:16
a forrás felhasználó

szavazat
0

Megjegyzés: ez a módszer a fajta munka. ha a kép kisebb, mint a Kamerák, akkor lépjünk részlegesen ki a képernyőn. Nem nagy dolog, de nem is olyan jók, mint a Fotók alkalmazást.

Először is fontos megérteni, hogy mi foglalkozunk 2 megtekintés, a Kamerák a képet, és a scrollview a Kamerák benne. Tehát, először állítsa a Kamerák, hogy a méret a képernyő:

 [myImageView setFrame:self.view.frame];

Ezután középre a képet a Kamerák:

 myImageView.contentMode = UIViewContentModeCenter;

Itt a teljes kódot:

- (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];
 }
Válaszolt 08/09/2009 03:14
a forrás felhasználó

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