छोटे होने पर UIScrollView की केंद्र सामग्री


140

मेरे UIImageViewअंदर एक UIScrollViewज़ूम है जिसे मैं ज़ूम करने और स्क्रॉल करने के लिए उपयोग करता हूं। यदि स्क्रॉल दृश्य की छवि / सामग्री स्क्रॉल दृश्य से बड़ी है, तो सब कुछ ठीक काम करता है। हालाँकि, जब छवि स्क्रॉल दृश्य से छोटी हो जाती है, तो यह स्क्रॉल दृश्य के ऊपरी बाएँ कोने पर चिपक जाती है। मैं इसे फ़ोटो ऐप की तरह, केंद्रित रखना चाहूंगा।

UIScrollViewछोटे होने पर सामग्री को केंद्रित रखने के बारे में कोई विचार या उदाहरण ?

मैं iPhone 3.0 के साथ काम कर रहा हूं।

निम्नलिखित कोड लगभग काम करता है। यदि मैं न्यूनतम ज़ूम स्तर तक पहुँचने के बाद इसे चुटकी बजाता हूँ तो छवि ऊपरी बाएँ कोने में लौट आती है।

- (void)loadView {
    [super loadView];

    // set up main scroll view
    imageScrollView = [[UIScrollView alloc] initWithFrame:[[self view] bounds]];
    [imageScrollView setBackgroundColor:[UIColor blackColor]];
    [imageScrollView setDelegate:self];
    [imageScrollView setBouncesZoom:YES];
    [[self view] addSubview:imageScrollView];

    UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"WeCanDoIt.png"]];
    [imageView setTag:ZOOM_VIEW_TAG];
    [imageScrollView setContentSize:[imageView frame].size];
    [imageScrollView addSubview:imageView];

    CGSize imageSize = imageView.image.size;
    [imageView release];

    CGSize maxSize = imageScrollView.frame.size;
    CGFloat widthRatio = maxSize.width / imageSize.width;
    CGFloat heightRatio = maxSize.height / imageSize.height;
    CGFloat initialZoom = (widthRatio > heightRatio) ? heightRatio : widthRatio;

    [imageScrollView setMinimumZoomScale:initialZoom];
    [imageScrollView setZoomScale:1];

    float topInset = (maxSize.height - imageSize.height) / 2.0;
    float sideInset = (maxSize.width - imageSize.width) / 2.0;
    if (topInset < 0.0) topInset = 0.0;
    if (sideInset < 0.0) sideInset = 0.0;
    [imageScrollView setContentInset:UIEdgeInsetsMake(topInset, sideInset, -topInset, -sideInset)];
}

- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
    return [imageScrollView viewWithTag:ZOOM_VIEW_TAG];
}

/************************************** NOTE **************************************/
/* The following delegate method works around a known bug in zoomToRect:animated: */
/* In the next release after 3.0 this workaround will no longer be necessary      */
/**********************************************************************************/
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale {
    [scrollView setZoomScale:scale+0.01 animated:NO];
    [scrollView setZoomScale:scale animated:NO];
    // END Bug workaround

    CGSize maxSize = imageScrollView.frame.size;
    CGSize viewSize = view.frame.size;
    float topInset = (maxSize.height - viewSize.height) / 2.0;
    float sideInset = (maxSize.width - viewSize.width) / 2.0;
    if (topInset < 0.0) topInset = 0.0;
    if (sideInset < 0.0) sideInset = 0.0;
    [imageScrollView setContentInset:UIEdgeInsetsMake(topInset, sideInset, -topInset, -sideInset)];
}

क्या आपने कभी इस समस्या को पूरी तरह से हल किया? मैं उसी मुद्दे से जूझ रहा हूं।
जोनाह

1
ध्यान दें: इनसेट की गणना करने के लिए इनिशियलज़ूम वैल्यू का उपयोग करें यदि यह एक (जूमिंग नहीं) है। जैसे इन पंक्तियों का उपयोग करें: topatset = (maxSize.height - imageSize.height * initialZoom) / 2.0; फ्लोट साइडइन्सेट = (मैक्ससाइज़-एक्सवर्टेशन - imageSize.width * initialZoom) / 2.0; और अंत में प्रारंभिक ज़ूम मान सेट करें [imageScrollView setZoomScale: initialZoom];
फेलिक्स

जवाबों:


228

मुझे बहुत सरल समाधान मिला है! स्क्रॉलविडेलेगेट में ज़ूम करते समय आपको बस अपने उप-केंद्र (इमेजव्यू) के केंद्र को अपडेट करना है। यदि जूम की गई इमेज स्क्रॉलव्यू से छोटी है तो सबव्यू को एडजस्ट करें। दूसरा सेंटर है (0,0)।

- (void)scrollViewDidZoom:(UIScrollView *)scrollView 
{
    UIView *subView = [scrollView.subviews objectAtIndex:0];

    CGFloat offsetX = MAX((scrollView.bounds.size.width - scrollView.contentSize.width) * 0.5, 0.0);
    CGFloat offsetY = MAX((scrollView.bounds.size.height - scrollView.contentSize.height) * 0.5, 0.0);

    subView.center = CGPointMake(scrollView.contentSize.width * 0.5 + offsetX, 
                                 scrollView.contentSize.height * 0.5 + offsetY);
}

5
मेरे लिए यह समाधान Liam के NYOBetterZoom का उपयोग करने की तुलना में अधिक झटकेदार है। शायद यह छवि के आकार आदि पर निर्भर करता है; नैतिक; उस समाधान का उपयोग करें जो आपकी आवश्यकताओं के अनुसार सबसे अच्छा हो
wuf810

2
इसके लिए Stackoverflow GOLD STAR। मैं इससे जूझ रहा था, फिर भी समाधान इतना आसान है।
n13

2
थोड़ा सरल करने के लिए:CGFloat offsetX = MAX((scrollView.bounds.size.width - scrollView.contentSize.width) * 0.5, 0.0);
मर्क आर

6
इस समायोजन ने मुझे तब मदद की जब स्क्रॉलव्यू में इनसेट थे: CGFloat offsetX = MAX((scrollView.bounds.size.width - scrollView.contentInset.left - scrollView.contentInset.right - scrollView.contentSize.width) * 0.5, 0.0); CGFloat offsetY = MAX((scrollView.bounds.size.height - scrollView.contentInset.top - scrollView.contentInset.bottom - scrollView.contentSize.height) * 0.5, 0.0);
किरन हार्पर

3
मैंने देखा कि यह, कई अन्य केंद्रित तकनीकों की तरह, उपयोग करते समय समस्याओं से ग्रस्त लगता है zoomToRect:contentInsetदृष्टिकोण का उपयोग करना बेहतर काम करता है, अगर आपको उस कार्यक्षमता की आवश्यकता होती है। अधिक जानकारी के लिए petersteinberger.com/blog/2013/how-to-center-uiscrollview देखें ।
मेटेज बुकोविंस्की

52

@ एवलिन कोर्डनर का जवाब वही था जिसने मेरे ऐप में सबसे अच्छा काम किया। अन्य विकल्पों की तुलना में बहुत कम कोड भी।

यहाँ स्विफ्ट संस्करण है अगर किसी को इसकी आवश्यकता है:

func scrollViewDidZoom(_ scrollView: UIScrollView) {
    let offsetX = max((scrollView.bounds.width - scrollView.contentSize.width) * 0.5, 0)
    let offsetY = max((scrollView.bounds.height - scrollView.contentSize.height) * 0.5, 0)
    scrollView.contentInset = UIEdgeInsetsMake(offsetY, offsetX, 0, 0)
}

4
यह एक महान काम करता है! सिकुड़ने के बाद दृश्य भी ठीक से एनिमेटेड।
कार्टर मेडलिन

4
मैं एक समारोह में इस कोड डाल दिया और यह भी में यह कहा जाता है viewDidLayoutSubviews यकीन है कि यह ठीक से शुरू में स्थापित किया गया था बनाने के लिए।
कार्टर मेडलिन

अच्छी कॉल @CarterMedlin ने मेरी स्विफ्ट 3 शुरुआती भार के साथ मुझे बहुत मदद की।
एजे हर्नांडेज़

यह काम करने लगता है, लेकिन मुझे समझ नहीं आ रहा है, क्योंकि यह हमेशा एक ही इनसेट की गणना करने के लिए लगता है: स्क्रॉल दृश्य की सीमाएं निश्चित हैं, जैसा कि सामग्री आकार है।
वदादी कार्तिक


25

ठीक है, मैं इस पर पिछले दो दिनों से लड़ रहा था और अंत में एक बहुत विश्वसनीय (अब तक ...) समाधान पर आया था मैंने सोचा कि मुझे इसे साझा करना चाहिए और दूसरों को कुछ दर्द से बचाना चाहिए। :) आप इस समाधान के साथ एक समस्या मिल जाए तो चिल्लाओ!

मैं मूल रूप से हर किसी के पास से गुजरा हूं: StackOverflow, Apple डेवलपर फ़ोरम, तीन20 के लिए कोड को देखा, स्क्रॉलिंगमैडनेस, स्क्रॉलटेस्टसाइट, आदि। मैंने UIImageView फ्रेम को बड़ा करने की कोशिश की है, UIScrollView के ऑफसेट और / या इनसेट के साथ खेल रहा हूं। ViewController, आदि से, लेकिन कुछ भी महान काम नहीं किया (जैसा कि बाकी सभी को भी पता चला है)।

इस पर सोने के बाद, मैंने वैकल्पिक कोणों के एक जोड़े की कोशिश की:

  1. UIImageView को उपवर्ग के रूप में बदलना, ताकि यह गतिशील रूप से अपने आकार में बदल जाए - यह बिल्कुल भी अच्छा काम नहीं करता था।
  2. UIScrollView को उपवर्ग के रूप में बदल देता है, इसलिए यह गतिशील रूप से स्वयं की सामग्री है - यह वह है जो मेरे लिए विजेता लगता है।

इस सबक्लासिंग UIScrollView मेथड के साथ, मैं contentOffset म्यूटेटर को ओवरराइड कर रहा हूँ, इसलिए यह {0,0} सेट नहीं कर रहा है जब इमेज व्यूपोर्ट से छोटी हो जाती है - इसके बजाय यह ऑफ़सेट सेट कर रहा है ताकि इमेज को व्यूपोर्ट में केंद्रित रखा जा सके। अब तक, यह हमेशा काम करने लगता है। मैंने इसे विस्तृत, लम्बी, छोटी और बड़ी छवियों के साथ जांचा है और इसमें "कार्य नहीं है लेकिन न्यूनतम ज़ूम पर चुटकी है" यह समस्या है।

मैंने github का एक उदाहरण प्रोजेक्ट अपलोड किया है जो इस समाधान का उपयोग करता है, आप इसे यहाँ पा सकते हैं: http://github.com/nyoron/NYOBetterZoom


2
रुचि रखने वालों के लिए - मैंने उपरोक्त लिंक की गई परियोजना को अपडेट कर दिया है, इसलिए यह व्यू कॉन्ट्रोलर पर थोड़ा कम निर्भर है, जो 'सही काम' कर रहा है, कस्टम UIScrollView अपने आप में अधिक विवरण का ध्यान रखता है।
लियाम जोन्स

2
लियाम, आप रॉक। मैं स्क्रॉलिंगमेडनेस के लेखक के रूप में यह कह रहा हूं। 3.2+ सेटिंग में iPad पर BTW करें। ScrollViewDidZoom (एक नया 3.2+ प्रतिनिधि विधि) में काम करता है।
एंड्री टारनटोसोव

कोड का बहुत साफ टुकड़ा। मैं थोड़ी देर के लिए इसके साथ अपना सिर खरोंच रहा हूं। करने के लिए परियोजना जोड़ा handyiphonecode.com
samvermette

यह भी खूब रही। धन्यवाद। यह मेरे UIStatusBar के छिपे होने की क्षतिपूर्ति नहीं कर रहा था, इसलिए मैंने लाइन anOffset.y = -(scrollViewSize.height - zoomViewSize.height) / 2.0को बदल दियाanOffset.y = (-(scrollViewSize.height - zoomViewSize.height) / 2.0) + 10;
गॉर्डन फोंटेनॉट

द्वि इरेडेमस का समाधान मेरी राय में बहुत अधिक सरल है।
ज्योजो कुदोर

23

यह कोड आईओएस के अधिकांश संस्करणों पर काम करना चाहिए (और 3.1 से ऊपर की ओर काम करने के लिए परीक्षण किया गया है)।

यह फोटोस्कॉलर के लिए Apple WWDC कोड पर आधारित है।

UIScrollView के अपने उपवर्ग में नीचे जोड़ें, और अपनी छवि या टाइलों वाले दृश्य के साथ टाइल का चयन करें।

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

3
यह स्वीकृत उत्तर होना चाहिए, क्योंकि यह सरल है। धन्यवाद। तुमने मेरी जान बचाई!!!!!! : D
डक

सभी iOS 3.2+ API कॉल्स को हटाने के बाद, सेंटरिंग लॉजिक केवल iOS 3.2+ वाले डिवाइस पर काम करने लगता है, न कि 3.1.3 (जंप, फ्लिकररी, रैंडम ऑफसेट)। मैंने 3.1.3 और 3.2+ के बीच फ्रेम की उत्पत्ति और आकार के आउटपुट की तुलना की है और भले ही वे किसी कारण से मेल खाते हों, बच्चे का दृश्य अभी भी गलत तरीके से मौजूद है। बहुत अजीब। केवल लियाम जौन के जवाब ने मेरे लिए काम किया।
डेविड एच।

1
@Erdemus और @JosephH दोनों समाधान काम करते हैं, लेकिन UIScrollViewउपवर्ग दृष्टिकोण बेहतर लगता है: यह तब लागू किया जाता है जब दृश्य पहली बार प्रदर्शित होता है + ज़ूम करते समय लगातार जारी रहता है (जबकि scrollViewDidZoomकेवल स्क्रॉल के अनुसार एक बार ही
कॉल

22

स्क्रोल व्यू के लिए बेहतर समाधान के लिए, जो ऑटोलेयआउट का उपयोग करता है, अपने स्क्रॉल व्यू के सबव्यू के फ्रेम को अपडेट करने के बजाय स्क्रॉल व्यू के कंटेंट इनसेट का उपयोग करें।

- (void)scrollViewDidZoom:(UIScrollView *)scrollView
{
    CGFloat offsetX = MAX((scrollView.bounds.size.width - scrollView.contentSize.width) * 0.5, 0.0);
    CGFloat offsetY = MAX((scrollView.bounds.size.height - scrollView.contentSize.height) * 0.5, 0.0);

    self.scrollView.contentInset = UIEdgeInsetsMake(offsetY, offsetX, 0.f, 0.f);
}

1
यह मेरे लिए काम करता है, हालांकि अगर छवि किसी भी तरह से शुरू होती है तो यह कोड (जब सीधे कहा जाता है) स्क्रॉलव्यू को अपडेट नहीं करता है। क्या मैं जरूरत कार्य करने की पहले रखा गया था UIViewहै कि अंदर UIScrollviewही केंद्र के लिए ( view.center = scrollview.center;और उसके बाद में) scrollViewDidZoomसेट view.frame.origin xऔर yकरने के लिए 0फिर से।
मोर्कसिनाब

मेरे लिए भी अच्छी तरह से काम करता है, लेकिन मैंने अपने मुख्य स्क्रॉल दृश्य पर कॉल dispatch_asyncकरने के लिए मुख्य कतार में किया । यह दृश्य को केंद्रित छवियों के साथ प्रदर्शित करता है। viewWillAppearscrollViewDidZoom:
पास्कल

viewDidLayoutSubviewsयह सुनिश्चित करने के लिए कि यह पहली बार देखने पर ठीक से सेट हो गया है, इस कोड में एक कॉल रखें ।
कार्टर मेडलिन

21

वर्तमान में मैं उपवर्ग UIScrollViewऔर ओवरराइडिंग setContentOffset:को समायोजित करने के आधार पर समायोजित कर रहा हूं contentSize। यह चुटकी और प्रोग्रामेटिक जूमिंग दोनों के साथ काम करता है।

@implementation HPCenteringScrollView

- (void)setContentOffset:(CGPoint)contentOffset
{
    const CGSize contentSize = self.contentSize;
    const CGSize scrollViewSize = self.bounds.size;

    if (contentSize.width < scrollViewSize.width)
    {
        contentOffset.x = -(scrollViewSize.width - contentSize.width) / 2.0;
    }

    if (contentSize.height < scrollViewSize.height)
    {
        contentOffset.y = -(scrollViewSize.height - contentSize.height) / 2.0;
    }

    [super setContentOffset:contentOffset];
}

@end

छोटा और मीठा होने के अलावा, यह कोड @Erdemus समाधान की तुलना में बहुत अधिक चिकनी ज़ूम पैदा करता है। आप इसे RMGallery डेमो में कार्रवाई में देख सकते हैं ।


6
इस पद्धति को लागू करने के लिए आपको UIScrollView को उप-करने की आवश्यकता नहीं है। Apple आपको प्रतिनिधि विधियों में स्क्रॉल और ज़ूम ईवेंट देखने की अनुमति देता है। विशेष रूप से: - (शून्य) स्क्रॉलव्यूडिजूम: (UIScrollView *) स्क्रॉल दृश्य;
Rog

1
सबसे अच्छा समाधान मैंने अभी तक देखा है (बाधाओं का उपयोग करते समय भी काम करता है)।
फ्रीज़लैब

12

मैंने एक दिन इस मुद्दे से लड़ते हुए बिताया है, और स्क्रॉलव्यूडाईंडग्लूमिंग: withView: atScale: को लागू करते हुए समाप्त किया है:

- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale {
    CGFloat screenWidth = [[UIScreen mainScreen] bounds].size.width;
    CGFloat screenHeight = [[UIScreen mainScreen] bounds].size.height;
    CGFloat viewWidth = view.frame.size.width;
    CGFloat viewHeight = view.frame.size.height;

    CGFloat x = 0;
    CGFloat y = 0;

    if(viewWidth < screenWidth) {
        x = screenWidth / 2;
    }
    if(viewHeight < screenHeight) {
        y = screenHeight / 2 ;
    }

    self.scrollView.contentInset = UIEdgeInsetsMake(y, x, y, x);
}

यह सुनिश्चित करता है कि जब छवि स्क्रीन से छोटी होती है, तब भी इसके चारों ओर पर्याप्त जगह होती है, ताकि आप इसे उस स्थान पर ले जा सकें जहाँ आप चाहते हैं।

(यह मानते हुए कि आपके UIScrollView में छवि को रखने के लिए UIImageView शामिल है)

अनिवार्य रूप से, यह क्या जाँचता है कि क्या आपकी छवि की चौड़ाई / ऊँचाई स्क्रीन की चौड़ाई / ऊँचाई से छोटी है, और यदि ऐसा है, तो आधे स्क्रीन की चौड़ाई / ऊँचाई का एक इनसेट बनाएं (यदि आप चाहते हैं कि यह छवि बड़ी हो सकती है) स्क्रीन सीमा से बाहर जाओ)।

ध्यान दें कि चूंकि यह एक UIScrollViewDelegate विधि है, इसलिए इसे अपने व्यू कंट्रोलर की घोषणा में जोड़ना न भूलें, ताकि बिल्ड समस्या से बचने के लिए।


7

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

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

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


1
प्रश्न में उदाहरण MyImagePicker है और यह, समान रूप से, इसी समस्या को प्रदर्शित करता है।
कॉलिन बैरेट

1
मुझे और अधिक स्पष्ट होना चाहिए था। प्रश्न में उदाहरण वास्तव में "PhotoScroller" नहीं "MyImagePicker" है। आप सही कह रहे हैं कि "MyImagePicker" ठीक से काम नहीं करता है। लेकिन, "PhotoScroller" करता है। कोशिश करो।
योना

क्या आपको याद है कि शायद WWDC वीडियो का शीर्षक जहां वे Photoscroller की चर्चा करते हैं।
ग्रेज़गोरज़ एडम हंकीविज़

1
इसे "Designing Apps With Scrolls Views" कहा जाता है।
जोनाह

2

ठीक है, यह समाधान मेरे लिए काम कर रहा है। मेरे पास इसका एक उपवर्ग है UIScrollViewजिसके संदर्भ में UIImageViewयह प्रदर्शित हो रहा है। जब भी UIScrollViewzooms, contentSize संपत्ति समायोजित किया जाता है। यह सेटर में है कि मैं UIImageViewउचित रूप से मापता हूं और इसके केंद्र की स्थिति को भी समायोजित करता हूं ।

-(void) setContentSize:(CGSize) size{
CGSize lSelfSize = self.frame.size;
CGPoint mid;
if(self.zoomScale >= self.minimumZoomScale){
    CGSize lImageSize = cachedImageView.initialSize;
    float newHeight = lImageSize.height * self.zoomScale;

    if (newHeight < lSelfSize.height ) {
        newHeight = lSelfSize.height;
    }
    size.height = newHeight;

    float newWidth = lImageSize.width * self.zoomScale;
    if (newWidth < lSelfSize.width ) {
        newWidth = lSelfSize.width;
    }
    size.width = newWidth;
    mid = CGPointMake(size.width/2, size.height/2);

}
else {
    mid = CGPointMake(lSelfSize.width/2, lSelfSize.height/2);
}

cachedImageView.center = mid;
[super  setContentSize:size];
[self printLocations];
NSLog(@"zoom %f setting size %f x %f",self.zoomScale,size.width,size.height);
}

ओवरटाइम मैं छवि का UIScrollViewआकार बदल देता हूं। UIScrollViewScrollview में भी मेरे द्वारा बनाए गए एक कस्टम वर्ग है।

-(void) resetSize{
    if (!scrollView){//scroll view is view containing imageview
        return;
    }

    CGSize lSize = scrollView.frame.size;

    CGSize lSelfSize = self.image.size; 
    float lWidth = lSize.width/lSelfSize.width;
    float lHeight = lSize.height/lSelfSize.height;

    // choose minimum scale so image width fits screen
    float factor  = (lWidth<lHeight)?lWidth:lHeight;

    initialSize.height = lSelfSize.height  * factor;
    initialSize.width = lSelfSize.width  * factor;

    [scrollView setContentSize:lSize];
    [scrollView setContentOffset:CGPointZero];
    scrollView.userInteractionEnabled = YES;
}

इन दो तरीकों के साथ मैं एक दृश्य के लिए सक्षम हूं जो फोटो ऐप की तरह ही व्यवहार करता है।


यह चाल करने के लिए लगता है, और यह एक काफी सरल उपाय है। कुछ ज़ूमिंग बदलाव सही नहीं हैं, लेकिन मेरा मानना ​​है कि इसे ठीक किया जा सकता है। मैं कुछ और प्रयोग करूंगा।
hpique

अद्यतन से पहले समाधान स्पष्ट था। अब यह थोड़ा भ्रमित करने वाला है। क्या आप स्पष्ट कर सकते हो?
hpique

2

जिस तरह से मैंने यह किया है वह पदानुक्रम में एक अतिरिक्त दृश्य जोड़ना है:

UIScrollView -> UIView -> UIImageView

अपने UIViewरूप में अपना समान पहलू अनुपात दें UIScrollView, और अपने UIImageViewको उसी में केन्द्रित करें ।


धन्यवाद, हैफिंच। इसके लिए भी प्रयास करेंगे। क्या आप नमूना कोड पोस्ट कर सकते हैं या मेरा नमूना कोड बदल सकते हैं यह दिखाने के लिए कि आप पदानुक्रम का निर्माण कैसे करते हैं?
hpique

इस तरह का काम करता है। इस तथ्य को छोड़कर कि क्योंकि UIView UIScrollView का आकार है, यदि छवि छोटी है (चित्र के बजाय परिदृश्य) तो आप स्क्रीन से छवि के भाग को स्क्रॉल कर सकते हैं। फ़ोटो ऐप इसकी अनुमति नहीं देता है और बहुत अच्छा लगता है।
जोनाह

2

मुझे पता है कि ऊपर दिए गए कुछ उत्तर सही हैं, लेकिन मैं सिर्फ कुछ स्पष्टीकरण के साथ अपना जवाब देना चाहता हूं, टिप्पणी आपको समझ में आएगी कि हम ऐसा क्यों करते हैं।

जब मैं पहली बार स्क्रॉल दृश्य लोड करता हूं, तो मैं इसे केंद्र बनाने के लिए निम्न कोड लिखता हूं, कृपया ध्यान दें कि हमने contentOffsetपहले सेट किया था, फिरcontentInset

    scrollView.maximumZoomScale = 8
    scrollView.minimumZoomScale = 1

    // set vContent frame
    vContent.frame = CGRect(x: 0,
                            y: 0  ,
                            width: vContentWidth,
                            height: vContentWidth)
    // set scrollView.contentSize
    scrollView.contentSize = vContent.frame.size

    //on the X direction, if contentSize.width > scrollView.bounds.with, move scrollView from 0 to offsetX to make it center(using `scrollView.contentOffset`)
    // if not, don't need to set offset, but we need to set contentInset to make it center.(using `scrollView.contentInset`)
    // so does the Y direction.
    let offsetX = max((scrollView.contentSize.width - scrollView.bounds.width) * 0.5, 0)
    let offsetY = max((scrollView.contentSize.height - scrollView.bounds.height) * 0.5, 0)
    scrollView.contentOffset = CGPoint(x: offsetX, y: offsetY)

    let topX = max((scrollView.bounds.width - scrollView.contentSize.width) * 0.5, 0)
    let topY = max((scrollView.bounds.height - scrollView.contentSize.height) * 0.5, 0)
    scrollView.contentInset = UIEdgeInsets(top: topY, left: topX, bottom: 0, right: 0)

फिर, जब मैं vContent चुटकी लेता हूं, तो मैं इसे केंद्र बनाने के लिए निम्न कोड लिखता हूं।

func scrollViewDidZoom(_ scrollView: UIScrollView) {
    //we just need to ensure that the content is in the center when the contentSize is less than scrollView.size.
    let topX = max((scrollView.bounds.width - scrollView.contentSize.width) * 0.5, 0)
    let topY = max((scrollView.bounds.height - scrollView.contentSize.height) * 0.5, 0)
    scrollView.contentInset = UIEdgeInsets(top: topY, left: topX, bottom: 0, right: 0)
}

2

यदि contentInsetकिसी और चीज की जरूरत नहीं है, तो इसका उपयोग स्क्रॉलव्यू की सामग्री को केंद्र में करने के लिए किया जा सकता है।

class ContentCenteringScrollView: UIScrollView {

    override var bounds: CGRect {
        didSet { updateContentInset() }
    }

    override var contentSize: CGSize {
        didSet { updateContentInset() }
    }

    private func updateContentInset() {
        var top = CGFloat(0)
        var left = CGFloat(0)
        if contentSize.width < bounds.width {
            left = (bounds.width - contentSize.width) / 2
        }
        if contentSize.height < bounds.height {
            top = (bounds.height - contentSize.height) / 2
        }
        contentInset = UIEdgeInsets(top: top, left: left, bottom: top, right: left)
    }
}

लाभ अगर यह दृष्टिकोण यह है कि आप अभी भी contentLayoutGuideस्क्रॉलव्यू के अंदर सामग्री रखने के लिए उपयोग कर सकते हैं

scrollView.addSubview(imageView)
imageView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
    imageView.leadingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.leadingAnchor),
    imageView.trailingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.trailingAnchor),
    imageView.topAnchor.constraint(equalTo: scrollView.contentLayoutGuide.topAnchor),
    imageView.bottomAnchor.constraint(equalTo: scrollView.contentLayoutGuide.bottomAnchor)
])

या सिर्फ Xcode के इंटरफ़ेस बिल्डर में सामग्री को खींचें और छोड़ें।


1

आप contentSizeUIScrollView की संपत्ति देख सकते हैं (कुंजी-मूल्य का अवलोकन या इसी तरह का उपयोग करके), और contentInsetजब भी contentSizeस्क्रॉल दृश्य के आकार से कम हो , तब स्वचालित रूप से समायोजित करें।


कोशिश करेंगे। क्या सामग्री का अवलोकन करने के बजाय UIScrollViewDelegate विधियों के साथ ऐसा करना संभव है?
hpique

सबसे अधिक संभावना; आप डेवलपर- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale (apple.com/iphone/library/documentation/UIKit/… ) पर उपयोग करते हैं, लेकिन मैं अवलोकन करना पसंद करूंगा क्योंकि अन्यथा आप नए ज़ूम स्केल को छोड़ देते हैं और इसे वैसे भी देखते हैं। (जब तक कि आप अपने विचारों के सापेक्ष आकार के आधार पर कुछ भयानक गणित नहीं निकाल सकते।)contentSize
टिम

धन्यवाद, टिम। ScrollViewDidEndZooming मैं क्या उपयोग कर रहा हूँ। प्रश्न में कोड देखें (मैंने आपके पहले उत्तर के बाद इसे जोड़ा है)। यह लगभग काम करता है। एकमात्र समस्या जो बनी हुई है कि अगर मैं मिनिममूमस्केल तक पहुंचने के बाद छवि को चुटकी लेता हूं, तो यह शीर्ष बाएं कोने में लौटता है।
hpique 5

क्या आपका मतलब है कि यह न्यूनतम ज़ूम स्केल के अलावा किसी भी पैमाने से पिंचिंग के लिए काम करता है (छवि को केंद्र में), और केवल तब टूटता है जब आप न्यूनतम पैमाने पर एक बार फिर से चुटकी लेने की कोशिश करते हैं? या क्या यह न्यूनतम पैमाने पर चुटकी भर काम नहीं करता है?
टिम

पहले वाला। यह न्यूनतम ज़ूम स्केल के अलावा किसी भी पैमाने से पिंचिंग के लिए छवि को केंद्र में रखता है, और यदि आप न्यूनतम पैमाने पर एक बार फिर से इसे चुटकी लेने की कोशिश करते हैं तो यह टूट जाता है। इसके अलावा, जब यह पहली बार न्यूनतम ज़ूम स्केल पर पहुंचता है, तो सामग्री संक्षेप में ऊपर से आने जैसी एनिमेटेड होती है, जो एक संक्षिप्त अजीब प्रभाव का कारण बनती है। यह कम से कम 3.0 सिम्युलेटर पर होता है।
hpique 8

1

सामग्री को केंद्र में रखने का एक सुंदर तरीका UISCrollViewयह है।

अपने सामग्री के आकार में एक पर्यवेक्षक जोड़ें 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


यह काम नहीं कर सका। ऐसा लगता है कि आप स्क्रॉलव्यू को केंद्रित कर रहे हैं और इसकी सामग्री को नहीं। खिड़की का आकार क्यों मायने रखता है? क्या कोड x स्थिति को भी ठीक नहीं करना चाहिए?
hpique

1

यह उस समस्या का मेरा समाधान है जो स्क्रॉलव्यू के अंदर किसी भी तरह के दृश्य के लिए बहुत अच्छा काम करता है।

-(void)scrollViewDidZoom:(__unused UIScrollView *)scrollView 
    {
    CGFloat top;
    CGFloat left;
    CGFloat bottom;
    CGFloat right;

    if (_scrollView.contentSize.width < scrollView.bounds.size.width) {
        DDLogInfo(@"contentSize %@",NSStringFromCGSize(_scrollView.contentSize));

        CGFloat width = (_scrollView.bounds.size.width-_scrollView.contentSize.width)/2.0;

        left = width;
        right = width;


    }else {
        left = kInset;
        right = kInset;
    }

    if (_scrollView.contentSize.height < scrollView.bounds.size.height) {

        CGFloat height = (_scrollView.bounds.size.height-_scrollView.contentSize.height)/2.0;

        top = height;
        bottom = height;

    }else {
        top = kInset;
        right = kInset;
    }

    _scrollView.contentInset = UIEdgeInsetsMake(top, left, bottom, right);



  if ([self.tiledScrollViewDelegate respondsToSelector:@selector(tiledScrollViewDidZoom:)])
  {
        [self.tiledScrollViewDelegate tiledScrollViewDidZoom:self];
  }
}

1

यहां बहुत सारे समाधान हैं, लेकिन मैं यहां अपना खुद का जोखिम डालूंगा। यह दो कारणों से अच्छा है: यह ज़ूमिंग अनुभव को गड़बड़ नहीं करता है, जैसा कि प्रगति में छवि दृश्य फ्रेम को अद्यतन करेगा, और यह मूल स्क्रॉल दृश्य इनसेट्स का भी सम्मान करता है (जैसे, अर्ध-पारदर्शी टूलबार आदि के सुशोभित संचालन के लिए xib या स्टोरीबोर्ड में परिभाषित) ।

सबसे पहले, एक छोटे सहायक को परिभाषित करें:

CGSize CGSizeWithAspectFit(CGSize containerSize, CGSize contentSize) {
    CGFloat containerAspect = containerSize.width / containerSize.height,
            contentAspect = contentSize.width / contentSize.height;

    CGFloat scale = containerAspect > contentAspect
                    ? containerSize.height / contentSize.height
                    : containerSize.width / contentSize.width;

    return CGSizeMake(contentSize.width * scale, contentSize.height * scale);
}

मूल इनसेट्स को परिभाषित करने के लिए, परिभाषित क्षेत्र:

UIEdgeInsets originalScrollViewInsets;

और कहीं न कहीं यह देखने के लिए इसे भरें:

originalScrollViewInsets = self.scrollView.contentInset;

UIImageView को UIScrollView में रखना (UIImage को स्वयं लोड किए गए संस्करण में है):

CGSize containerSize = self.scrollView.bounds.size;
containerSize.height -= originalScrollViewInsets.top + originalScrollViewInsets.bottom;
containerSize.width -= originalScrollViewInsets.left + originalScrollViewInsets.right;

CGSize contentSize = CGSizeWithAspectFit(containerSize, loadedImage.size);

UIImageView *imageView = [[UIImageView alloc] initWithFrame:(CGRect) { CGPointZero, contentSize }];
imageView.autoresizingMask = UIViewAutoresizingNone;
imageView.contentMode = UIViewContentModeScaleAspectFit;
imageView.image = loadedImage;

[self.scrollView addSubview:imageView];
self.scrollView.contentSize = contentSize;

[self centerImageViewInScrollView];

स्क्रॉल दृश्य दृश्य: उस स्क्रॉल दृश्य के लिए UIScrollViewDelegate से:

- (void)scrollViewDidZoom:(UIScrollView *)scrollView {
    if (scrollView == self.scrollView) {
        [self centerImageViewInScrollView];
    }
}

अंत में, खुद को केंद्रित करना:

- (void)centerImageViewInScrollView {
    CGFloat excessiveWidth = MAX(0.0, self.scrollView.bounds.size.width - self.scrollView.contentSize.width),
            excessiveHeight = MAX(0.0, self.scrollView.bounds.size.height - self.scrollView.contentSize.height),
            insetX = excessiveWidth / 2.0,
            insetY = excessiveHeight / 2.0;

    self.scrollView.contentInset = UIEdgeInsetsMake(
            MAX(insetY, originalScrollViewInsets.top),
            MAX(insetX, originalScrollViewInsets.left),
            MAX(insetY, originalScrollViewInsets.bottom),
            MAX(insetX, originalScrollViewInsets.right)
    );
}

मैंने अभी तक अभिविन्यास परिवर्तन का परीक्षण नहीं किया (यानी UIScrollView का आकार बदलने के लिए उचित प्रतिक्रिया), लेकिन इसके लिए ठीक होना अपेक्षाकृत आसान होना चाहिए।


1

आप पाएंगे कि एर्डेमस द्वारा पोस्ट किया गया समाधान काम करता है, लेकिन ... कुछ ऐसे मामले हैं जहां स्क्रॉलव्यूडज़ूम विधि लागू नहीं होती है और आपकी छवि शीर्ष बाएं कोने में अटक जाती है। एक सरल समाधान विधि को स्पष्ट रूप से लागू करना है जब आप शुरू में एक छवि प्रदर्शित करते हैं, जैसे:

[self scrollViewDidZoom: scrollView];

कई मामलों में, आप इस पद्धति को दो बार लागू कर सकते हैं, लेकिन यह इस विषय के कुछ अन्य उत्तरों की तुलना में एक क्लीनर समाधान है।


1

Apple का फोटो स्क्रोलर उदाहरण वही करता है जो आप ढूंढ रहे हैं। इसे अपने UIScrollView Subclass में रखें और _zoomView को अपने UIImageView में बदलें।

-(void)layoutSubviews{
  [super layoutSubviews];
  // center the zoom view as it becomes smaller than the size of the screen
  CGSize boundsSize = self.bounds.size;
  CGRect frameToCenter = self.imageView.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;
  }
  self.imageView.frame = frameToCenter; 
}

Apple का फोटो स्क्रोलर नमूना कोड


1

एनीमेशन को अच्छी तरह से प्रवाहित करने के लिए, सेट करें

self.scrollview.bouncesZoom = NO;

और इस फ़ंक्शन का उपयोग करें ( इस उत्तर में विधि का उपयोग करके केंद्र ढूंढना )

- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale {
    [UIView animateWithDuration:0.2 animations:^{
        float offsetX = MAX((scrollView.bounds.size.width-scrollView.contentSize.width)/2, 0);
        float offsetY = MAX((scrollView.bounds.size.height-scrollView.contentSize.height)/2, 0);
        self.imageCoverView.center = CGPointMake(scrollView.contentSize.width*0.5+offsetX, scrollView.contentSize.height*0.5+offsetY);
    }];
}

यह शेख़ी प्रभाव पैदा करता है, लेकिन पहले से किसी भी अचानक आंदोलनों को शामिल नहीं करता है।


1

बस स्विफ्ट में स्वीकृत उत्तर है, लेकिन प्रतिनिधि का उपयोग किए बिना उपवर्ग के बिना

func centerScrollViewContents(scrollView: UIScrollView) {
    let contentSize = scrollView.contentSize
    let scrollViewSize = scrollView.frame.size;
    var contentOffset = scrollView.contentOffset;

    if (contentSize.width < scrollViewSize.width) {
        contentOffset.x = -(scrollViewSize.width - contentSize.width) / 2.0
    }

    if (contentSize.height < scrollViewSize.height) {
        contentOffset.y = -(scrollViewSize.height - contentSize.height) / 2.0
    }

    scrollView.setContentOffset(contentOffset, animated: false)
}

// UIScrollViewDelegate    
func scrollViewDidZoom(scrollView: UIScrollView) {
    centerScrollViewContents(scrollView)
}

1

मामले में अपने भीतर imageView प्रारंभिक विशिष्ट चौड़ाई है (उदाहरण के लिए 300) और तुम सिर्फ इसकी चौड़ाई केंद्रित करने के लिए चाहते हैं केवल अपनी आरंभिक की तुलना में छोटे आप भी ज़ूम इस पराक्रम मदद चौड़ाई।

 func scrollViewDidZoom(scrollView: UIScrollView){
    if imageView.frame.size.width < 300{
        imageView.center.x = self.view.frame.width/2
    }
  }

0

यहाँ वर्तमान तरीका मैं यह काम कर रहा हूँ। यह बेहतर है, लेकिन अभी भी सही नहीं है। सेटिंग का प्रयास करें:

 myScrollView.bouncesZoom = YES; 

इस समस्या को ठीक करने के लिए जब केंद्र में नहीं है minZoomScale

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
CGSize screenSize = [[self view] bounds].size;//[[UIScreen mainScreen] bounds].size;//
CGSize photoSize = [yourImage size];
CGFloat topInset = (screenSize.height - photoSize.height * [myScrollView zoomScale]) / 2.0;
CGFloat sideInset = (screenSize.width - photoSize.width * [myScrollView zoomScale]) / 2.0;

if (topInset < 0.0)
{ topInset = 0.0; }
if (sideInset < 0.0)
{ sideInset = 0.0; } 
[myScrollView setContentInset:UIEdgeInsetsMake(topInset, sideInset, -topInset, -sideInset)];
ApplicationDelegate *appDelegate = (ApplicationDelegate *)[[UIApplication sharedApplication] delegate];

CGFloat scrollViewHeight; //Used later to calculate the height of the scrollView
if (appDelegate.navigationController.navigationBar.hidden == YES) //If the NavBar is Hidden, set scrollViewHeight to 480
{ scrollViewHeight = 480; }
if (appDelegate.navigationController.navigationBar.hidden == NO) //If the NavBar not Hidden, set scrollViewHeight to 360
{ scrollViewHeight = 368; }

imageView.frame = CGRectMake(0, 0, CGImageGetWidth(yourImage)* [myScrollView zoomScale], CGImageGetHeight(yourImage)* [myScrollView zoomScale]);

[imageView setContentMode:UIViewContentModeCenter];
}

इसके अलावा, मैं इमेज को ज़ूम आउट करने के बाद साइड से चिपके रहने से रोकने के लिए करता हूं।

- (void) scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale {
myScrollView.frame = CGRectMake(0, 0, 320, 420);
 //put the correct parameters for your scroll view width and height above
}

हाय जोनाह। ऐसा लगता है कि हम कुछ समय से एक ही मुद्दे से निपट रहे हैं। आपके दो समाधानों की जाँच करेगा और जल्द ही उत्तर देगा।
hpique

हाय जोनाह, मैंने आपके नवीनतम समाधान की कोशिश की। हालाँकि, अस्थायी अस्थायी क्या है? मैंने अस्थायी इमेज = imageView.image डालने की कोशिश की; हालाँकि, एक बार जब मैं ज़ूम करता हूं, तो छवि गायब हो जाती है। धन्यवाद, पन्नग
२६:२१

पन्नग, अस्थायी नाम खराब था। इसे myImage कहा जाना चाहिए क्योंकि यह सिर्फ जो भी तस्वीर आप उपयोग कर रहे हैं। गलतफहमी के लिए खेद है।
जोनाह

0

ठीक है, मुझे लगता है कि मुझे इस समस्या का बहुत अच्छा समाधान मिल गया है। चाल लगातार imageView'sफ्रेम को पढ़ने के लिए है। मुझे लगता है कि यह लगातार काम करने से 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

बस पेजिंग को अक्षम करें, इसलिए यह ठीक काम करेगा:

scrollview.pagingEnabled = NO;

0

मेरे साथ भी ठीक यही समस्या थी। यहाँ है कि मैं कैसे हल किया

इस कोड को परिणाम के रूप में बुलाया जाना चाहिए scrollView:DidScroll:

CGFloat imageHeight = self.imageView.frame.size.width * self.imageView.image.size.height / self.imageView.image.size.width;
BOOL imageSmallerThanContent = (imageHeight < self.scrollview.frame.size.height) ? YES : NO;
CGFloat topOffset = (self.imageView.frame.size.height - imageHeight) / 2;

// If image is not large enough setup content offset in a way that image is centered and not vertically scrollable
if (imageSmallerThanContent) {
     topOffset = topOffset - ((self.scrollview.frame.size.height - imageHeight)/2);
}

self.scrollview.contentInset = UIEdgeInsetsMake(topOffset * -1, 0, topOffset * -1, 0);

0

हालाँकि यह सवाल थोड़ा पुराना है लेकिन समस्या अभी भी मौजूद है। मैं में इसे हल Xcode 7 (इस मामले में सबसे ऊपर आइटम के ऊर्ध्वाधर अंतरिक्ष बाधा बनाकर topLabelsuperViews करने के लिए) ( scrollView) एक शीर्ष IBOutletहै और फिर उसके लगातार हर बार scrollview के subviews के ऊंचाई के आधार पर सामग्री में परिवर्तन recalculating ( topLabelऔर bottomLabel)।

class MyViewController: UIViewController {

    @IBOutlet weak var scrollView: UIScrollView!
    @IBOutlet weak var topLabel: UILabel!
    @IBOutlet weak var bottomLabel: UILabel!
    @IBOutlet weak var toTopConstraint: NSLayoutConstraint!

    override func viewDidLayoutSubviews() {
        let heightOfScrollViewContents = (topLabel.frame.origin.y + topLabel.frame.size.height - bottomLabel.frame.origin.y)
        // In my case abs() delivers the perfect result, but you could also check if the heightOfScrollViewContents is greater than 0.
        toTopConstraint.constant = abs((scrollView.frame.height - heightOfScrollViewContents) / 2)
    }

    func refreshContents() {
        // Set the label's text …

        self.view.layoutIfNeeded()
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.