বিভিন্ন ডিভাইস ওরিয়েন্টেশনগুলিতে ইউআইকোলিকেশনভিউসেল আকার পরিবর্তন করুন


100

আমি একটি UICollectionViewসাথে ব্যবহার করছি UICollectionViewFlowLayout

আমি প্রতিটি কক্ষের আকারটি সেট করে দিয়েছি

collectionView:layout:sizeForItemAtIndexPath:

প্রতিকৃতি থেকে ল্যান্ডস্কেপে স্যুইচ করার সময়, আমি ঘরগুলির প্যাডিং জায়গা ছাড়াই কালেকশন ভিউয়ের আকার পুরোপুরি ফিট করার জন্য প্রতিটি কক্ষের আকারকে সামঞ্জস্য করতে চাই।

প্রশ্নসমূহ:

1) ঘূর্ণন ইভেন্টের পরে কোনও ঘরের আকার কীভাবে পরিবর্তন করবেন?

2) এবং আরও ভাল, কীভাবে লেআউটটি তৈরি করবেন যেখানে কোষগুলি সর্বদা পর্দার পুরো আকারের সাথে ফিট করে?


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

@ মাইকেলজি.ইমনস: আপনার উত্তরটি আরও ভাল কাজ করবে যেখানে সংগ্রহের ভিউ একবারে কেবল একটি একক পূর্ণ আকারের ঘর প্রদর্শন করে। সেক্ষেত্রে, এটা জ্ঞান UIKit ঘূর্ণন উপর অভিযোগ যেমন কুয়েরিং হবেন তোলে sizeForItemAtIndexPathকল করার আগে didRotateFromInterfaceOrientation। তবে, স্ক্রিনের একাধিক কক্ষের সাথে সংগ্রহের দৃশ্যের জন্য, ঘোরার আগে লেআউটটিকে অকার্যকর করে ভিউটি ঘোরার আগে আকারে একটি বাজে, দৃশ্যমান লাফ দেয়। এই পরিস্থিতিতে আমি বিশ্বাস করি যে আমার উত্তরটি এখনও সবচেয়ে সঠিক বাস্তবায়ন।
অনুসরণ

@ ফলোবেন সম্মত হন যে প্রতিটি ব্যবহারের ক্ষেত্রে বিভিন্ন ক্ষেত্রে তাদের সমস্যা রয়েছে। যদিও এই ক্ষেত্রে, ওপি নির্দেশ করে I would like to adjust the size of each cell to **completely fit the size of the CollectionView**যা আমার উত্তরে প্রস্তাবিত সমাধানটি হ'ল। যদি আপনি আমার উত্তরে আমার সমাধানটি অন্তর্ভুক্ত করতে পারেন এবং কোন পন্থাটি আমার পক্ষে যথেষ্ট উপযুক্ত হবে তার মধ্যে কোন পদ্ধতির সবচেয়ে ভাল কাজ করে তা নোট করে দিতে পারেন।
স্মারক

উত্তর:


200

1) আপনি একাধিক লেআউট অবজেক্টগুলি বজায় রাখতে এবং এটিকে সরিয়ে নিতে পারবেন তবে এর সহজ উপায় আছে। কেবলমাত্র আপনার UICollectionViewControllerসাবক্লাসে নিম্নলিখিতগুলি যুক্ত করুন এবং প্রয়োজনীয় আকারগুলি মেশান:

- (CGSize)collectionView:(UICollectionView *)collectionView
                  layout:(UICollectionViewLayout *)collectionViewLayout
  sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{    
    // Adjust cell size for orientation
    if (UIDeviceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation])) {
        return CGSizeMake(170.f, 170.f);
    }
    return CGSizeMake(192.f, 192.f);
}

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
    [self.collectionView performBatchUpdates:nil completion:nil];
}

কলিং -performBatchUpdates:completion:লেআউটটিকে অকার্যকর করে দেবে এবং অ্যানিমেশন সহ ঘরগুলিকে পুনরায় আকার দেবে (যদি আপনার কোনও অতিরিক্ত সমন্বয় সম্পাদন না করা হয় তবে আপনি কেবল উভয় ব্লক প্যারামগুলিতেই শূন্য করতে পারেন)।

2) আইটেমের আকারগুলিকে হার্ডকোডিংয়ের পরিবর্তে -collectionView:layout:sizeForItemAtIndexPath, আপনি কেবলমাত্র পর্দায় ফিট করতে চান সেই সংখ্যার দ্বারা সংগ্রহের ভিউয়ের সীমানার উচ্চতা বা প্রস্থকে ভাগ করুন। উচ্চতাটি যদি আপনার সংগ্রহভিউটি অনুভূমিকভাবে স্ক্রল করে বা প্রস্থে উল্লম্বভাবে স্ক্রোল করে তবে প্রস্থটি ব্যবহার করুন।


4
কেন শুধু ফোন [self.collectionView.collectionViewLayout invalidateLayout];করবেন না ?
ব্যবহারকারী 102008

7
@ user102008 কলিং invalidateLayoutসঠিক আকারের সাথে কোষগুলি পুনরায় আঁকবে, তবে -performBatchUpdates:completion:পরিবর্তনগুলি অ্যানিমেটেড করবে, যা দেখতে অনেক সুন্দর আইএমএইচও দেখায়।
অনুসরণ

4
আমার ক্ষেত্রে কোডটি পর্দা স্ক্রোল না করা পর্যন্ত কালেকশনভিউসেলটি আকার পরিবর্তন করে না।
newguy

9
didRotateFromInterfaceOrientationআইওএস 8
জ্যানোস

8
IOS8, আমি আহ্বান করছি coordinator.animateAlongsideTransitionমধ্যে viewWillTransitionToSize, এবং কলিং performBatchUpdatesতার মধ্যে animationব্লক। এটি একটি দুর্দান্ত অ্যানিমেশন প্রভাব দেয়।
মাইক তাভারনে

33

যদি আপনি অতিরিক্ত অ্যানিমেশনগুলি আনতে চান না performBatchUpdates:completion:, তবে কেবলমাত্র invalidateLayoutসংগ্রহ ভিউলআউটকে পুনরায় লোড করতে বাধ্য করুন।

- (void)viewWillLayoutSubviews
{
    [super viewWillLayoutSubviews];
    [self.collectionView.collectionViewLayout invalidateLayout];
}

13

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

self.portraitLayout = [[UICollectionViewFlowLayout alloc] init];
self.landscapeLayout = [[UICollectionViewFlowLayout alloc] init];

UIInterfaceOrientation orientationOnLunch = [[UIApplication sharedApplication] statusBarOrientation];

if (UIInterfaceOrientationIsPortrait(orientationOnLunch)) {
    [self.menuCollectionView setCollectionViewLayout:self.portraitLayout];
} else {
    [self.menuCollectionView setCollectionViewLayout:self.landscapeLayout];
}

তারপরে আমি কেবল এইভাবে আমার সংগ্রহ ভিউফ্লোএলআউটডেলগেট পদ্ধতিগুলি পরিবর্তন করেছি

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
    CGSize returnSize = CGSizeZero;

    if (collectionViewLayout == self.portraitLayout) {
        returnSize = CGSizeMake(230.0, 120.0);
    } else {
        returnSize = CGSizeMake(315.0, 120.0);
    }

    return returnSize;
}

সর্বশেষে আমি আবর্তনের সময় একটি বিন্যাস থেকে অন্যটিতে স্যুইচ করি

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation{
    if (UIInterfaceOrientationIsPortrait(fromInterfaceOrientation)) {
        [self.menuCollectionView setCollectionViewLayout:self.landscapeLayout animated:YES];
    } else {
        [self.menuCollectionView setCollectionViewLayout:self.portraitLayout animated:YES];
    }
}

8

সংগ্রহ দেখার ঘরের আকার নির্ধারণের জন্য একটি সহজ উপায় রয়েছে:

UICollectionViewFlowLayout *layout = (id) self.collectionView.collectionViewLayout;
layout.itemSize = CGSizeMake(cellSize, cellSize);

এটি অ্যানিমেটেবল যদিও নিশ্চিত না Not


: আমি সঙ্গে হ্যায় ফেং কাও এর উত্তর viewWillLayoutSubviews এই ভিতরে ব্যবহার ছিল stackoverflow.com/a/14776915/2298002
গ্রিনহাউজ

7

সুইফট: সংগ্রহ ভিউ সেল যা স্ক্রিনের উচ্চতার n%

আমার কাছে এমন একটি ঘর দরকার ছিল যা দেখের উচ্চতার একটি নির্দিষ্ট শতাংশ ছিল এবং ডিভাইস রোটেশনের সাথে আকার পরিবর্তন করবে।

উপরের সাহায্যে, এখানে সমাধান

override func viewDidLoad() {
    super.viewDidLoad()
    automaticallyAdjustsScrollViewInsets = false
    // if inside nav controller set to true
}

override func willRotateToInterfaceOrientation(toInterfaceOrientation: UIInterfaceOrientation, duration: NSTimeInterval) {
    collectionViewLayout.invalidateLayout()
}

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
    return CGSize(width: 100, height: collectionView.frame.height * 0.9)
}

2

আপনি যদি ব্যবহার করছেন autolayout। আপনি invalidate layoutঘোরানোর সময় এবং সামঞ্জস্য করার সময় আপনার ভিউ কন্ট্রোলারে কেবল দরকারoffset আপনার প্রবাহ বিন্যাস সাবক্লাসে

সুতরাং, আপনার দর্শন নিয়ামক -

override func willRotateToInterfaceOrientation(toInterfaceOrientation:     UIInterfaceOrientation, duration: NSTimeInterval) {
    self.galleryCollectionView.collectionViewLayout.invalidateLayout()
}

এবং আপনার মধ্যে FlowLayout Subclass

override func prepareLayout() {
    if self.collectionView!.indexPathsForVisibleItems().count > 0{
    var currentIndex : CGFloat!
    currentIndex = CGFloat((self.collectionView!.indexPathsForVisibleItems()[0] as! NSIndexPath).row)
    if let currentVal = currentIndex{
        self.collectionView!.contentOffset = CGPointMake(currentIndex * self.collectionView!.frame.width, self.collectionView!.contentOffset.y);
    }   
    }     
}

4
এটি দুর্দান্ত কাজ করে! willRotateToInterfaceOrientationআইওএস 8-এ অবমুক্ত করা হয়েছে তবে viewWillTransitionToSizeএটির জন্য ঠিক তেমন কাজ করে।
keegan3d
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.