केंद्रित UIImageView, फ़ोटो ऐप्लिकेशन की तरह साथ UIScrollView

वोट
37

मैं एक छवि सामग्री को देखने के साथ स्क्रॉल दृश्य है करना चाहते हैं। छवि वास्तव में नक्शा जो स्क्रीन की तुलना में बहुत बड़ा है। नक्शा स्क्रॉल दृश्य के मध्य में शुरू में होना चाहिए, फ़ोटो एप्लिकेशन में फ़ोटो जैसे कि जब आप लैंडस्केप ओरिएंटेशन के लिए iPhone बदल जाते हैं।

वैकल्पिक

मैं एक ही समय में सही ज़ूम और स्क्रॉल के साथ केंद्र में नक्शे के लिए प्रबंधन नहीं किया। बशर्ते कि नक्शा छवि स्क्रीन के ऊपर (पोर्ट्रेट ओरिएंटेशन में) से शुरू होता है, कोड तरह दिखता है:

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

जब मैं केंद्र के लिए छवि फ्रेम ले जाते हैं, छवि इसके फ्रेम नीचे के ऊपर से ही बढ़ता है। मैं MapView के साथ चारों ओर खेलने के लिए बदलने गतिशील imageView के फ्रेम में बदलाव के साथ, की कोशिश की। कुछ भी नहीं अब तक मेरे लिए काम करता है।

12/03/2009 को 12:56
का स्रोत उपयोगकर्ता
अन्य भाषाओं में...                            


11 जवाब

वोट
40

इस कोड को आईओएस के सबसे संस्करणों पर काम करना चाहिए (और ऊपर की तरफ 3.1 पर काम करने के परीक्षण किया गया है)।

यह योना के जवाब में बताया गया एप्पल 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;
}
13/08/2010 को 17:42
का स्रोत उपयोगकर्ता

वोट
23

यहाँ मैं क्या करने पर विचार करना चाहते हैं, समाधान में के रूप में यह सेब के फ़ोटो एप्लिकेशन की तरह वास्तव में बर्ताव करता है। मैं समाधान है कि प्रयोग किया जाता का उपयोग कर किया गया था:

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

recenter करने के लिए, लेकिन क्योंकि के बाद संभवत: ज़ूम किया गया था, यह तो त्वरित सेंटर जो बहुत अन-सेक्सी था में 'कूद' उछाल था मुझे लगता है कि समाधान पसंद नहीं आया। पता चला है कि अगर आप काफी ठीक उसी तर्क लेकिन इस प्रतिनिधि समारोह में कार्य करें:

-(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आप उपयोग कर रहे।

03/02/2010 को 03:51
का स्रोत उपयोगकर्ता

वोट
7

एप्पल iphone डेवलपर कार्यक्रम के सभी सदस्यों को 2010 WWDC सत्र वीडियो जारी किया है। चर्चा के विषयों में से एक है कि वे कैसे फ़ोटो एप्लिकेशन बनाया है !!! वे कदम से काफ़ी मिलती-जुलती एप्लिकेशन कदम का निर्माण और मुक्त करने के लिए सभी कोड उपलब्ध कराया है।

यह या तो निजी एपीआई का उपयोग नहीं करता। मुझे नहीं गैर प्रकटीकरण समझौते की वजह से यहाँ कोड के किसी भी कहें, लेकिन यहाँ नमूना कोड डाउनलोड करने के लिए एक कड़ी है सकते हैं। आप शायद पहुँच प्राप्त करने के लिए लॉग इन करना होगा।

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

और, यहाँ आइट्यून्स 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

20/06/2010 को 20:48
का स्रोत उपयोगकर्ता

वोट
2

मुझे लगता है कि आप निर्धारित करने की आवश्यकता है कि UIScrollViewके contentOffset

12/03/2009 को 20:16
का स्रोत उपयोगकर्ता

वोट
1

यह मेरे लिए काम किया:

- (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 निर्धारित किया है।

31/03/2009 को 09:15
का स्रोत उपयोगकर्ता

वोट
1

काश यह इतना आसान नहीं था। मैं नेट पर कुछ शोध किया और पाया कि यह सिर्फ मेरी समस्या नहीं है, लेकिन बहुत से लोगों के साथ-साथ एक ही मुद्दा नहीं iPhone पर है, लेकिन पर एप्पल के डेस्कटॉप कोको के साथ संघर्ष कर रहे हैं। निम्नलिखित लिंक देखें:

http://www.iphonedevsdk.com/forum/iphone-sdk-development/5740-uiimageview-uiscrollview.html
वर्णित समाधान छवि की संपत्ति UIViewContentModeScaleAspectFit पर आधारित है, लेकिन दुर्भाग्य से यह बहुत अच्छी तरह से व्याप्ति छवि है काम नहीं करता है केंद्रित है और ठीक से होती है, लेकिन उछल क्षेत्र चित्र से काफी बड़ा हो रहा है।

यह आदमी जवाब नहीं मिला या तो:
http://discussions.apple.com/thread.jspa?messageID=8322675

और अंत में, एप्पल के डेस्कटॉप कोको पर एक ही समस्या:
http://www.cocoadev.com/index.pl?CenteringInsideNSScrollView
मैं समाधान काम करता है लगता है, लेकिन यह NSClipView, जो iPhone पर नहीं है पर आधारित है ...

किसी को कुछ iPhone पर काम कर समाधान है?

13/03/2009 को 08:29
का स्रोत उपयोगकर्ता

वोट
0

यहाँ एक वैकल्पिक समाधान, @ JosephH के जवाब के समान है, लेकिन यह एक खाते में छवि के वास्तविक आयाम ले जाता है। तो यह है कि जब उपयोगकर्ता पैन / ज़ूम, आप स्क्रीन पर अधिक खाली स्थान के आवश्यकता से की आवश्यकता नहीं है। यह उदाहरण के लिए एक आम समस्या है जब एक चित्र स्क्रीन पर एक परिदृश्य छवि दिखाने है। जब पूरी छवि स्क्रीन (पहलू फ़िट) पर है खाली स्थान के ऊपर और छवि के नीचे होने के लिए वहाँ जा रहा है। तब, जब उसे ज़ूम, अन्य समाधान, विचार है कि छवि के भाग के रूप में खाली स्थान के क्योंकि यह imageView में है। वे आपको स्क्रीन बंद छवि के बहुमत पैन, बस खाली स्थान के दृश्यमान रखते करने देगा। इस उपयोगकर्ता के लिए बुरा लग रहा है।

इस वर्ग के साथ, आप यह imageView इसके साथ काम कर रहा है पारित करने के लिए की आवश्यकता है। मैं इसे ऑटो का पता लगाने के लिए है करने के लिए परीक्षा थी, लेकिन इस तेजी से होता है और आप सभी गति आप में प्राप्त कर सकते हैं चाहता हूँ layoutSubviewsविधि।

नोट: है के रूप में, यह जरूरी है कि autolayout 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
    }
}
05/05/2016 को 09:56
का स्रोत उपयोगकर्ता

वोट
0

Monotouch में मेरे लिए काम किया है।

this._scroll.ScrollRectToVisible(new RectangleF(_scroll.ContentSize.Width/2, _scroll.ContentSize.Height/2,1,1),false);
08/08/2012 को 15:45
का स्रोत उपयोगकर्ता

वोट
0

की सामग्री के केंद्र के लिए एक सुंदर तरीका UISCrollViewयह है।

करने के लिए एक पर्यवेक्षक जोड़े contentSize अपने की UIScrollViewहै, तो इस विधि हर सामग्री परिवर्तन बुलाया जाएगा ...

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

अपने पर्यवेक्षक पद्धति पर अब:

- (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 ); }
  • आप बदलना चाहिए [pointer viewWithTag:100]। अपनी सामग्री को देखने से बदलें UIView

    • इसके अलावा बदलने imageGalleryअपने विंडो का आकार की ओर इशारा करते।

यह सामग्री हर अपने आकार परिवर्तन के केंद्र सही कर देंगे।

नोट: एक ही तरीका है इस सामग्री बहुत अच्छी तरह से काम करता है नहीं है के मानक ज़ूम कार्यक्षमता के साथ है UIScrollView

03/11/2009 को 18:14
का स्रोत उपयोगकर्ता

वोट
0

ठीक है, मुझे लगता है कि मैं इस समस्या का एक बहुत अच्छा समाधान मिल गया है। चाल लगातार 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];
}
04/10/2009 को 03:16
का स्रोत उपयोगकर्ता

वोट
0

नोट: काम करता है की इस पद्धति तरह। यदि छवि imageView से छोटी है, यह स्क्रीन बंद आंशिक रूप से स्क्रॉल करेगा। नहीं एक बड़ी बात, लेकिन यह भी रूप में फ़ोटो एप्लिकेशन के रूप में अच्छा नहीं।

सबसे पहले, यह समझने के लिए कि हम 2 बार देखा गया, उस में छवि के साथ imageView, और उस में imageView साथ scrollview साथ काम कर रहे महत्वपूर्ण है। तो, पहले स्क्रीन के आकार को imageView सेट करें:

 [myImageView setFrame:self.view.frame];

फिर, imageView में अपनी छवि को केंद्र:

 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];
 }
08/09/2009 को 03:14
का स्रोत उपयोगकर्ता

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