যখন ছোট হয় তখন ইউআইএসক্রোলভিউয়ের কেন্দ্রিয় সামগ্রী


140

আমার UIImageViewভিতরে একটি রয়েছে UIScrollViewযা আমি জুমিং এবং স্ক্রোলিংয়ের জন্য ব্যবহার করি। স্ক্রোল ভিউয়ের চিত্র / সামগ্রী যদি স্ক্রোল ভিউয়ের চেয়ে বড় হয় তবে সবকিছু ঠিকঠাক কাজ করে। যাইহোক, চিত্রটি যখন স্ক্রোল ভিউয়ের চেয়ে ছোট হয়ে যায়, তখন এটি স্ক্রোল দৃশ্যের উপরের বাম কোণে আটকে যায়। আমি ফটোগুলি অ্যাপ্লিকেশনটির মতো এটিও কেন্দ্রিক রাখতে চাই।

UIScrollViewকেন্দ্রিক বিষয়বস্তু যখন ছোট হয় তখন সে সম্পর্কে কোনও ধারণা বা উদাহরণ ?

আমি আইফোন 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
মনোযোগ: ইনসেটটি গণনা করতে প্রাথমিক জুম মানটি ব্যবহার করুন যদি এটি না হয় তবে (জুমিং নেই)। উদাহরণস্বরূপ এই লাইনগুলি ব্যবহার করুন: ফ্লোট টপইনসেট = (ম্যাক্স সাইজ.হাইট - ইমেজ সাইজ.হাইট * ইনিশিয়াল জুম) / 2.0; ফ্লোট সাইডআইনেসেট = (ম্যাক্স সাইজ.উইথথ - ইমেজসাইজ.উইথথ * ইনিশিয়ালজুম) / 2.0; এবং শেষ পর্যন্ত প্রাথমিক জুম মান সেট করুন [চিত্রসক্রোলভিউ সেটজুমস্কেল: ইনিশিয়ালজুম];
ফেলিক্স

উত্তর:


228

আমি খুব সহজ সমাধান পেয়েছি! আপনার যা দরকার তা হ'ল স্ক্রোলভিউ ডেলেগেটে জুম করার সময় আপনার সাবভিউ (চিত্রদর্শন) এর কেন্দ্র আপডেট করুন। জুমযুক্ত চিত্র যদি স্ক্রোলভিউয়ের চেয়ে ছোট হয় তবে সাব-ভিউ অ্যাডজাস্ট করুন else অন্যটি কেন্দ্রটি (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
আমার কাছে এই সমাধানটি লিয়ামের এনওয়াইওবাটারজুম ব্যবহার করার চেয়ে আরও বিড়ম্বিত। হতে পারে এটি চিত্রের আকারের উপর নির্ভর করে ইত্যাদি নৈতিক; আপনার প্রয়োজন অনুসারে সবচেয়ে উপযুক্ত সমাধানটি ব্যবহার করুন
wuf810

2
এর জন্য স্ট্যাকওভারফ্লো গোল্ড স্টার। আমি এটি নিয়ে লড়াই করছিলাম, তবুও সমাধানটি এত সহজ।
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পদ্ধতির ভাল কাজ করে, যদি আপনি যে কার্যকারিতা প্রয়োজন ঘটে। আরও তথ্যের জন্য পিটারস্টেইনবার্গার / ব্লগ/2013/how-to-center-uiscrolview দেখুন ।
মতেজ বুকভিনস্কি

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
আমি এই কোডটিকে একটি মজাদার মধ্যে রেখেছি এবং এটি প্রাথমিকভাবে সঠিকভাবে সেট আপ করা হয়েছে তা নিশ্চিত করার জন্য এটি ডিডলয়আউটসুভিউগুলিতে ডেকে আনে
কার্টার মেডলিন

ভাল কল @ কার্টারমেডলিন আমার সুইফট 3 প্রাথমিক লোডের সাথে আমাকে অনেক সহায়তা করেছে।
এজে হার্নান্দেজ

এটি কাজ করে বলে মনে হচ্ছে তবে কেন বুঝতে পারছি না, যেহেতু এটি সর্বদা একই ইনসেটগুলি গণনা করে: স্ক্রোল দর্শনের সীমানা স্থির করা হয়, যেমন বিষয়বস্তুর আকার।
ভাদ্দাদি কার্তিক

contentSize পরিবর্তন যখন জুম scrollView আকার শুধুমাত্র সংশোধন করা হয়েছে
মাইকেল Ziobro

25

ঠিক আছে, আমি গত দু'দিন ধরে লড়াই চালিয়ে যাচ্ছি এবং অবশেষে একটি দুর্দান্ত নির্ভরযোগ্য (এখনও অবধি ...) সমাধানে এসেছি আমি ভেবেছিলাম আমার এটি ভাগ করে নেওয়া উচিত এবং অন্যদের কিছুটা বেদনা বাঁচাতে হবে। :) আপনি যদি এই সমাধানটিতে কোনও সমস্যা খুঁজে পান তবে চিৎকার করুন!

আমি সবার কাছে যা করেছি তা পেরেছি: স্ট্যাকওভারফ্লো, অ্যাপল বিকাশকারী ফোরামগুলি অনুসন্ধান করে তিনটি কোডের জন্য স্ক্রোলিংম্যাডনেস, স্ক্রোলটেষ্টসুয়েট ইত্যাদির দিকে নজর রেখেছি, আমি ইউআইআইসেজভিউ ফ্রেমটি প্রসারিত করার চেষ্টা করেছি, ইউআইএসক্রোলভিউয়ের অফসেট এবং / বা ইনসেটের সাথে খেলছি ভিউকন্ট্রোলার ইত্যাদি থেকে তবে কিছুই দুর্দান্ত কাজ করেনি (যেমন সবাই প্রত্যেকেও খুঁজে পেয়েছে)।

এটির পরে ঘুমানোর পরে, আমি কয়েকটি বিকল্প কোণ চেষ্টা করেছি:

  1. ইউআইআইমেজভিউকে সাবক্লাসিং করা যাতে এটি নিজস্ব আকার পরিবর্তনশীল - এটি মোটেই ভাল কাজ করে না।
  2. ইউআইএসক্রোলভিউকে সাবক্লাসিং করা যাতে এটি নিজস্ব সামগ্রীতে পরিবর্তন ঘটেঅফ্যাসেটটি গতিশীলভাবে - এটিই আমার পক্ষে বিজয়ী বলে মনে হয়।

এই সাবক্লাসিং ইউআইএসক্রোলভিউ পদ্ধতির সাহায্যে আমি সামগ্রীটি অফসেট মিউটেটরটিকে ওভাররাইড করছি যাতে চিত্রটি ভিউপোর্টের চেয়ে ছোট আকারের করা হয় না - পরিবর্তে এটি অফসেটটি সেট করে রাখে যে চিত্রটি ভিউপোর্টে কেন্দ্রে রাখা হবে। এখনও অবধি এটি সর্বদা কাজ করে বলে মনে হচ্ছে। আমি এটি প্রশস্ত, লম্বা, ক্ষুদ্র ও বৃহত্তর চিত্র সহ পরীক্ষা করেছি এবং "ন্যূনতম জুম এ চিমটি দিয়ে এটি ভেঙে দেয়" সমস্যা নেই।

আমি গিথুবে একটি উদাহরণ প্রকল্প আপলোড করেছি যা এই সমাধানটি ব্যবহার করে, আপনি এটি এখানে খুঁজে পেতে পারেন: http://github.com/nyoron/NYOBetterZoom


2
আগ্রহীদের জন্য - আমি উপরের লিঙ্কযুক্ত প্রকল্পটি আপডেট করেছি যাতে এটি ভিউকন্ট্রোলারটি 'সঠিক জিনিস' করায় কিছুটা নির্ভরশীল, কাস্টম ইউআইএসক্রোলভিউ নিজেই বিশদটির আরও যত্ন নেয়।
লিয়াম জোনস

2
লিয়াম, তুমি রক কর আমি এটি স্ক্রোলিংম্যাডনেসের লেখক হিসাবে বলছি। আইপ্যাডে বিটিডব্লিউ আইপিডে ৩.২++ সেটিং সামগ্রী অন্তর্ভুক্ত করুন স্ক্রোলভিউডিজম ইনসেট করুন (একটি নতুন 3.2+ প্রতিনিধি পদ্ধতি) জাস্ট ওয়ার্কস।
আন্দ্রে তারানসভ

কোডের খুব ঝরঝরে টুকরা। আমি কিছুক্ষণের জন্য এটি দিয়ে আমার মাথা আঁচড়াচ্ছি। প্রজেক্টটি হ্যান্ডিআইফোনকোড.কম-এ যুক্ত করা হয়েছে
সমারমেট

এটা অসাধারণ. ধন্যবাদ. এটা আমার UIStatusBar পুষিয়ে নি যদিও গোপন থাকবে না, তাই আমি লাইন পরিবর্তিত anOffset.y = -(scrollViewSize.height - zoomViewSize.height) / 2.0করতেanOffset.y = (-(scrollViewSize.height - zoomViewSize.height) / 2.0) + 10;
গর্ডন Fontenot

দ্বি এরডিমাস প্রদত্ত সমাধানটি আমার মতে অনেক সহজ।
gyozo kudor

23

এই কোডটি আইওএসের বেশিরভাগ সংস্করণে কাজ করা উচিত (এবং উপরে 3.1 তে কাজ করার জন্য পরীক্ষা করা হয়েছে)।

এটি ফটোকলারের জন্য অ্যাপল ডাব্লুডাব্লুডিসি কোডের উপর ভিত্তি করে।

আপনার ইউআইএসক্রোলভিউয়ের সাবক্লাসে নীচে যুক্ত করুন, এবং টাইলকন্টেইনারভিউটি আপনার চিত্র বা টাইলযুক্ত ভিউয়ের সাথে প্রতিস্থাপন করুন:

- (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
এটি গ্রহণযোগ্য উত্তর হওয়া উচিত, কারণ এটি সহজ। ধন্যবাদ। তুমি আমার জীবন বাঁচিয়েছো !!!!!! : ডি
হাঁস

সমস্ত আইওএস 3.2+ এপিআই কলগুলি সরিয়ে দেওয়ার পরে, কেন্দ্রীভূত যুক্তি কেবল আইওএস 3.2+ এবং 3.1.3 নয় এমন ডিভাইসগুলিতে কাজ করবে বলে মনে হচ্ছে (ঝাঁকুনি, ঝলকানি, এলোমেলো অফসেট পায়)। আমি ফ্রেম উত্স এবং আকারের ফলাফলগুলি 3.1.3 এবং 3.2+ এর মধ্যে তুলনা করেছি এবং যদিও তারা মিলছে কিছু কারণে, সন্তানের দৃষ্টিভঙ্গি এখনও ভুলভাবে অবস্থিত হয়। খুব অদ্ভুত. কেবল লিয়াম জোনের উত্তরই আমার পক্ষে কার্যকর হয়েছিল।
ডেভিড এইচ

1
উভয় @ এরডেমাস এবং @ জোসেফএইচ সমাধানগুলি কাজ করে তবে 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মূল কাতারে একটি কাজ করেছি viewWillAppearযেখানে আমি scrollViewDidZoom:আমার প্রধান স্ক্রোল ভিউটিতে কল করি। এটি কেন্দ্রিক চিত্রগুলির সাথে দর্শনটিকে উপস্থিত করে তোলে।
পাস্কাল

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

সংক্ষিপ্ত এবং মিষ্টি হওয়া ছাড়াও এই কোডটি @ এরডেমাস সলিউশনের তুলনায় অনেক মসৃণ জুম তৈরি করে। আপনি এটি আরএমজিয়ালারি ডেমোতে ক্রিয়াতে দেখতে পাচ্ছেন


6
এই পদ্ধতিটি প্রয়োগ করতে আপনার ইউআইএসক্রোলভিউ সাবক্লাস করার দরকার নেই। অ্যাপল আপনাকে প্রতিনিধি পদ্ধতিতে স্ক্রোল এবং জুম ইভেন্টগুলি দেখার অনুমতি দেয়। বিশেষত: - (অকার্যকর) স্ক্রোলভিউডিডজুম: (ইউআইএসক্রোলভিউ *) স্ক্রোলভিউ;
Rog

1
আমি এখনও দেখেছি সেরা সমাধান (সীমাবদ্ধতা ব্যবহার করার পরেও কাজ করুন)।
ফ্রিজল্যাব

12

আমি এই সমস্যাটির সাথে লড়াই করে একদিন কাটিয়েছি, এবং স্ক্রোলভিউডিডইডজুমিং: উইভ: এটস্কেল: নীচে হিসাবে প্রয়োগ করেছি :

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

এটি নিশ্চিত করে যে চিত্রটি যখন স্ক্রিনের চেয়ে ছোট হয়, তখনও এর চারপাশে পর্যাপ্ত জায়গা রয়েছে যাতে আপনি এটি যথাযথ স্থানে রাখতে পারেন।

(ধরে নিচ্ছেন যে আপনার ইউআইএসক্রোলভিউতে ছবিটি ধরে রাখতে একটি ইউআইআইমেজভিউ রয়েছে)

মূলত, এটি যা করে তা আপনার চিত্রের দৃশ্যের প্রস্থ / উচ্চতা যে পর্দার প্রস্থ / উচ্চতা এর চেয়ে কম ছোট কিনা তা যাচাই করা হয় এবং যদি তা হয় তবে অর্ধেক পর্দার প্রস্থ / উচ্চতার একটি ইনসেট তৈরি করুন (আপনি যদি চিত্রটি চান তবে আপনি সম্ভবত এটি আরও বৃহত্তর করতে পারেন স্ক্রিনের সীমা ছাড়িয়ে যান)।

নোট করুন যেহেতু এটি একটি ইউআইএসক্রোলভিউ ডেলেগেট পদ্ধতি, তাই আপনার বিল্ড ইস্যুটি এড়াতে এটিকে আপনার ভিউ কন্ট্রোলারের ঘোষণায় যুক্ত করতে ভুলবেন না।


7

অ্যাপল আইফোন বিকাশকারী প্রোগ্রামের সকল সদস্যের জন্য ২০১০ ডাব্লুডাব্লুডিসি সেশন ভিডিও প্রকাশ করেছে। আলোচিত বিষয়গুলির একটি হ'ল তারা কীভাবে ফটো অ্যাপ্লিকেশন তৈরি করলেন !!! তারা ধাপে ধাপে একটি খুব অনুরূপ অ্যাপ্লিকেশন তৈরি করে এবং সমস্ত কোডকে বিনামূল্যে উপলব্ধ করে।

এটি প্রাইভেট এপিও ব্যবহার করে না। আমি প্রকাশের চুক্তি না করার কারণে এখানে কোডের কোনওটিই রাখতে পারি না, তবে এখানে নমুনা কোড ডাউনলোডের লিঙ্ক। অ্যাক্সেস পেতে আপনার সম্ভবত লগইন করতে হবে।

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

এবং, এখানে আইটিউনস ডাব্লুডাব্লুডিসি পৃষ্ঠার লিঙ্ক:

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
প্রশ্নের উদাহরণটি মাইআইমেজপিকার এবং এটি হাসিখুশিভাবে এই একই সমস্যাটি দেখায়।
কলিন ব্যারেট

1
আমার আরো স্পষ্ট করা উচিত। প্রশ্নের উদাহরণ আসলে "ফটোস্ক্রোলার" "মাই আইমেজপিকার" নয়। আপনি ঠিক বলেছেন যে "মাই আইমেজপিকার" সঠিকভাবে কাজ করে না। তবে, "ফটোস্ক্রোলার" করে। চেষ্টা করে দেখুন
জোনা

আপনি সম্ভবত ডাব্লুডাব্লুডিসি ভিডিওর শিরোনাম মনে রেখেছেন যেখানে তারা ফটোস্রোলার নিয়ে আলোচনা করেন?
গ্রজেগোর্জ অ্যাডাম হানকিউইকজ

1
একে "স্ক্রোল ভিউগুলি সহ ডিজাইনিং অ্যাপস" বলা হয়।
জোনা

2

ঠিক আছে, এই সমাধানটি আমার পক্ষে কাজ করছে। এটিতে প্রদর্শিত UIScrollViewরেফারেন্স সহ আমার একটি সাবক্লাস রয়েছে UIImageView। যখনই UIScrollViewজুম আসে তখন সামগ্রী সামগ্রী আকারটি সামঞ্জস্য করা হয়। এটি সেটারে আমি 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;
}

এই দুটি পদ্ধতির সাহায্যে আমি এমন একটি দৃষ্টিভঙ্গি রাখতে সক্ষম হয়েছি যা কেবল ফটো অ্যাপের মতো আচরণ করে।


এটি কৌশলটি মনে হচ্ছে এবং এটি মোটামুটি সহজ সমাধান। কিছু জুমিং ট্রানজিশনগুলি নিখুঁত নয়, তবে আমি বিশ্বাস করি এটি ঠিক করা যেতে পারে। আমি আরও কিছু পরীক্ষা করব।
এইচপিফিক

সমাধানটি আপডেটের আগে পরিষ্কার ছিল। এখন এটি কিছুটা বিভ্রান্তিকর। আপনি কি স্পষ্ট করতে পারেন?
এইচপিফিক

2

আমি যেভাবে এটি করেছি তা হায়ারার্কিতে অতিরিক্ত ভিউ যুক্ত করা:

UIScrollView -> UIView -> UIImageView

আপনার UIViewমতো একই অনুপাতের অনুপাত দিন UIScrollViewএবং এটিতে আপনার কেন্দ্র করুন UIImageView


ধন্যবাদ, হ্যাটফিন্চ এটিও চেষ্টা করবে। আপনি কীভাবে ভিউ হায়ারার্কি তৈরি করেন তা দেখানোর জন্য আপনি কী নমুনা কোড পোস্ট করতে বা আমার নমুনা কোড পরিবর্তন করতে পারেন?
এইচপিক

এই ধরণের কাজ। ইউআইভিউভটি ইউআইএসক্রোলভিউজের আকার হওয়ায় এই চিত্রটি বাদে যদি চিত্রটি ছোট হয় (যেমন প্রতিকৃতির পরিবর্তে ল্যান্ডস্কেপ) আপনি পর্দার বাইরে চিত্রের কিছু অংশ স্ক্রোল করতে পারেন। ফটোগুলি অ্যাপ্লিকেশন এটিকে অনুমতি দেয় না এবং দেখতে খুব সুন্দর দেখায়।
জোনা

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)

তারপরে, আমি যখন ভিচন্টিকে চিম্টি দিই, তখন এটি কেন্দ্রের জন্য আমি নীচের কোডটি লিখি।

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)
])

বা কেবল এক্সকোডের ইন্টারফেস বিল্ডারে সামগ্রীটি টেনে আনুন।


1

আপনি contentSizeইউআইএসক্রোলভিউয়ের সম্পত্তি (কী-মান পর্যবেক্ষণ বা অনুরূপ ব্যবহার করে) দেখতে পেলেন এবং contentInsetযখনই contentSizeপরিবর্তনগুলি স্ক্রোল দর্শনের আকারের চেয়ে কম হবে তখন স্বয়ংক্রিয়ভাবে সামঞ্জস্য করতে পারেন।


চেস্টা করবো. কনটেন্টসাইজ পর্যবেক্ষণের পরিবর্তে কি ইউআইএসক্রলভিউ ডেলেগেট পদ্ধতিগুলির সাথে এটি করা সম্ভব?
hpique

সম্ভবত; আপনি ব্যবহার করবেন - (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale( ডেভেলপার.এপ্লে /contentSize আইফোন / লিবারি / ডকুমেন্টেশন / ইউআইকিট / at এ বর্ণিত ) তবে আমি পর্যবেক্ষণ করতে পছন্দ করব কারণ অন্যথায় আপনি নতুন জুম স্কেলটি বাতিল করে এবং যেকোন উপায়ে এটির সন্ধান করতে চান। (যদি না আপনি নিজের মতামতের তুলনামূলক আকারের উপর ভিত্তি করে কিছু দুর্দান্ত ম্যাথটি টানতে পারেন)
টিম

ধন্যবাদ, টিম স্ক্রোলভিউডিডএন্ডজুমিং আমি ব্যবহার করছি। প্রশ্নযুক্ত কোডটি দেখুন (আমি এটি আপনার প্রথম উত্তরের পরে যুক্ত করেছি)। এটি প্রায় কাজ করে। কেবলমাত্র যদি সমস্যাটি থেকে যায় তবে যদি আমি ন্যূনতম জুমস্কেলটি পৌঁছানোর পরে চিত্রটি চিমটি করে ফেলে, এটি উপরের বাম কোণায় ফিরে আসে।
এইচপিক

আপনি কী ন্যূনতম জুম স্কেল ব্যতীত অন্য কোনও স্কেল থেকে পিনিংয়ের জন্য কাজ করে (চিত্রটি কেন্দ্র করে) তা বোঝায় এবং আপনি সর্বনিম্ন স্কেলে একবার একবার চিমটি দেওয়ার চেষ্টা করলেই কেবল ব্রেক হয়ে যায়? বা এটি সর্বনিম্ন স্কেলে চিমটি দেওয়ার জন্য কোনও কাজ করে না?
টিম

প্রথমটি. এটি ন্যূনতম জুম স্কেল ব্যতীত অন্য কোনও স্কেল থেকে পিনিংয়ের জন্য চিত্রটিকে কেন্দ্র করে এবং ন্যূনতম স্কেলে একবার একবার যদি আপনি এটি চিমটি দেওয়ার চেষ্টা করেন তবে তা ভেঙে যায়। এছাড়াও, যখন এটি সর্বনিম্ন জুম স্কেলে প্রথমবারে পৌঁছে যায়, তখন সামগ্রীটি উপরে থেকে আসার মতো সংক্ষিপ্তভাবে অ্যানিমেটেড হয়, যা সংক্ষিপ্ত অদ্ভুত প্রভাবের কারণ হয়। এটি অন্তত 3.0 সিমুলেটারে ঘটে ulator
এইচপিক

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 পজিশনটি ঠিক করা উচিত নয়?
এইচপিক

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

এখানে প্রচুর সমাধান রয়েছে তবে আমি নিজেরাই এখানে ঝুঁকিপূর্ণ রাখব। এটি দুটি কারণে ভাল: এটি জুম করার অভিজ্ঞতাটি নিয়ে গোলমাল করবেন না, যেমনটি চিত্রের দৃশ্যের ফ্রেম আপডেট করার ক্ষেত্রে রয়েছে এবং এটি মূল স্ক্রোল ভিউ ইনসেটগুলিকেও সম্মান করে (বলুন, অর্ধ-স্বচ্ছ সরঞ্জামদণ্ডগুলির ক্রেফুল হ্যান্ডলিংয়ের জন্য এক্সবি বা স্টোরিবোর্ডে সংজ্ঞায়িত করা ইত্যাদি) ।

প্রথমে একটি ছোট সহায়ককে সংজ্ঞা দিন:

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;

ইউআইসাইজভিউটি ইউআইএসক্রোলভিউতে রাখার জন্য (ধরে নিই যে ইউআইআইমেজ নিজেই লোডডাইমেজ ভেরিতে রয়েছে):

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];

স্ক্রোলভিউডিডজুম: ইউআইএসক্রোলভিউ থেকে এই স্ক্রোল দর্শনের জন্য:

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

আমি এখনও ওরিয়েন্টেশন পরিবর্তনের পরীক্ষা করি নি (অর্থাৎ ইউআইএসক্রোলভিউ নিজেই আকার পরিবর্তন করার জন্য যথাযথ প্রতিক্রিয়া), তবে এটির জন্য অপেক্ষাকৃত সহজ হওয়া উচিত।


1

আপনি দেখতে পাবেন যে এরডেমাসের পোস্ট করা সমাধানটি কাজ করে, কিন্তু… এমন কিছু ঘটনা রয়েছে যেখানে স্ক্রোলভিউডিজম পদ্ধতিটি না চাওয়া হয় এবং আপনার চিত্রটি বাম দিকের উপরের অংশে আটকে থাকে। একটি সহজ সমাধান হ'ল স্পষ্টভাবে পদ্ধতিতে অনুরোধ করা যখন আপনি প্রথমদিকে কোনও চিত্র প্রদর্শিত করেন, যেমন:

[self scrollViewDidZoom: scrollView];

অনেক ক্ষেত্রে, আপনি এই পদ্ধতিটি দু'বার কল করতে পারেন, তবে এটি এই বিষয়ের অন্যান্য উত্তরগুলির তুলনায় এটি একটি পরিষ্কার সমাধান।


1

অ্যাপলের ফটো স্ক্রোলার উদাহরণটি আপনি যা খুঁজছেন ঠিক তেমনই করে। এটি আপনার ইউআইএসক্রোলভিউ সাবক্লাসে রাখুন এবং _জুমভিউটিকে আপনার ইউআইআইমেজভিউতে পরিবর্তন করুন।

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

অ্যাপলের ফটো স্ক্রোলার নমুনা কোড


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
}

হাই জোনা দেখে মনে হচ্ছে আমরা কিছুক্ষণ একই সমস্যা নিয়ে কাজ করছি। আপনার দুটি সমাধান পরীক্ষা করে দেখুন এবং শীঘ্রই উত্তর দিন।
এইচপিক

হাই জোনা, আমি আপনার সর্বশেষ সমাধানটি চেষ্টা করেছি। তবে অস্থায়ী ইমেজ কি? অস্থায়ী আইমেজ = ইমেজভিউ.আইমেজ লাগানোর চেষ্টা করেছি; তবে আমি একবার জুম করলে ছবিটি অদৃশ্য হয়ে যায়। ধন্যবাদ, পানগনাগ
২২:২২ এ

পানগনাগ, অস্থায়ী ইমেজটির নাম খারাপ ছিল। এটিকে মাই আইমেজ বলা উচিত কারণ এটি আপনি যে কোনও চিত্রই ব্যবহার করছেন is বিভ্রান্তির জন্য দুঃখিত.
জোনা

0

ঠিক আছে, আমি মনে করি আমি এই সমস্যার খুব ভাল সমাধান পেয়েছি। কৌশলটি হ'ল imageView'sফ্রেমটি নিয়মিতভাবে সামঞ্জস্য করা । আমি ক্রমাগত contentInsetsবা সামঞ্জস্য করার চেয়ে এটি আরও ভাল কাজ করে দেখিcontentOffSets । পোর্ট্রেট এবং ল্যান্ডস্কেপ উভয় চিত্রের জন্য আমাকে কিছুটা অতিরিক্ত কোড যুক্ত করতে হয়েছিল add

কোডটি এখানে:

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

যদিও প্রশ্নটি কিছুটা পুরাতন তবুও সমস্যাটি এখনও রয়েছে। আমি এক্সকোড 7 এ সমাধান করে উপরের আইটেমের উল্লম্ব স্থান সীমাবদ্ধ করে (এই ক্ষেত্রে ক্ষেত্রে topLabel) সুপারভিউস (দ্য scrollView) এর শীর্ষে IBOutletএবং তারপরে ধ্রুবকটিকে পুনরুদ্ধার করে যখনই লিখিত সামগ্রীটি স্ক্রোলভিউর সাবউভিউগুলির উচ্চতার উপর নির্ভর করে ( 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()
    }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.