ইউআইকোলিকেশনভিউ বর্তমান দৃশ্যমান ঘর সূচক দেখুন


115

আমি UICollectionViewআমার আইপ্যাড অ্যাপ্লিকেশনটিতে প্রথমবার ব্যবহার করছি । আমি এটি সেট করে রেখেছি UICollectionViewযে এর আকার এবং কক্ষের আকার একই, মানে একবারে একবারে ঘর প্রদর্শিত হবে।

সমস্যা: এখন যখন ব্যবহারকারী ইউআইকোলিকেশনভিউ স্ক্রোল করবেন তখন আমার কোন কোষটি দৃশ্যমান তা জানতে হবে আমাকে পরিবর্তনের ক্ষেত্রে অন্যান্য ইউআই উপাদানগুলি আপডেট করতে হবে। আমি এর জন্য কোনও প্রতিনিধি পদ্ধতি পাইনি। আমি কীভাবে এটি অর্জন করতে পারি?

কোড:

[self.mainImageCollection setTag:MAIN_IMAGE_COLLECTION_VIEW];
[self.mainImageCollection registerClass:[InspirationMainImageCollectionCell class] forCellWithReuseIdentifier:@"cellIdentifier"];
[self.mainImageFlowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
[self.mainImageFlowLayout setMinimumInteritemSpacing:0.0f];
[self.mainImageFlowLayout setMinimumLineSpacing:0.0f];
self.mainImageFlowLayout.minimumLineSpacing = 0;
[self.mainImageCollection setPagingEnabled:YES];
[self.mainImageCollection setShowsHorizontalScrollIndicator:NO];
[self.mainImageCollection setCollectionViewLayout:self.mainImageFlowLayout];

আমি যা চেষ্টা করেছি:

হিসাবে UICollectionViewকনফার্ম হিসাবে UIScrollView, যখন আমি ব্যবহারকারীর স্ক্রোলটি UIScrollViewDelegateপদ্ধতিটি দিয়ে শেষ হয়

-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView

তবে উপরের ফাংশনের ভিতরে আমি কীভাবে বর্তমান দৃশ্যমান সেল সূচক পেতে পারি UICollectionView???


self.collectionViewFloors.indexPathsForVisibleItems
Aznix

উত্তর:


130

পদ্ধতি [সংগ্রহভিউ দৃশ্যমান সেলগুলি] আপনার পছন্দমতো সমস্ত দৃশ্যমান সেল অ্যারে দেয়। আপনি যখন পেতে চান এটি ব্যবহার করুন

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
    for (UICollectionViewCell *cell in [self.mainImageCollection visibleCells]) {
        NSIndexPath *indexPath = [self.mainImageCollection indexPathForCell:cell];
        NSLog(@"%@",indexPath);
    }
}

সুইফট 5 এ আপডেট করুন:

func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
    for cell in yourCollectionView.visibleCells {
        let indexPath = yourCollectionView.indexPath(for: cell)
        print(indexPath)
    }
}

আপনি কি দয়া করে সে সম্পর্কে বিস্তারিত বলতে পারেন যেখানে সেল.ইমেইম্যাজেশন সংগ্রহটি এসেছে? আপনার আরও বিশদ জন্য অগ্রিম অনেক ধন্যবাদ।
বেনিয়ামিন ম্যাকফেরেন

@ বেঞ্জামিন এমসিফেরেন এটি আপনার সংগ্রহের ভিউ ব্যবহার করেছেন।
লে সাং

10
scrollViewDidScroll:প্রতিনিধি পদ্ধতি স্ক্রল দৃশ্য আপডেটগুলি যখনই কোনো স্ক্রল শেষ (এবং সম্ভবত এখানে একটি ভাল পছন্দ হয়) প্রদান করে। scrollViewDidEndDecelerating:প্রতিনিধি পদ্ধতির বিপরীতে যা কেবল তখনই ডাকা হয় যখন স্ক্রোল ভিউ " [একটি বড় স্ক্রোল থেকে] থামার জন্য কল্পনা করা হয়" (ইউআইএসক্রোলভিউ শিরোনাম দেখুন)।
স্যাম স্পেন্সার

1
আইআইআরসি, ..DidScrollএকটি সংক্ষিপ্ত স্ক্রোলের সময়ও অনেকবার কল করা হয়। কেউ কি করতে চায় তার উপর নির্ভর করে একটি ভাল জিনিস হতে পারে বা নাও হতে পারে।
টুলমেকারস্টেভ

4
আইওএস 10 যেহেতু এখন সরাসরি ইন্ডেক্সপ্যাথসভিজিবলআইটেমগুলি সরাসরি ব্যবহার করাও সম্ভব :)
বেন

174

indexPathsForVisibleItemsবেশিরভাগ পরিস্থিতিতে কাজ করতে পারে তবে কখনও কখনও এটি একাধিক সূচক পাথের সাথে একটি অ্যারের ফেরত দেয় এবং এটি আপনি যেটি চান তা নির্ধারণ করা জটিল হতে পারে। এই পরিস্থিতিতে আপনি এই জাতীয় কিছু করতে পারেন:

CGRect visibleRect = (CGRect){.origin = self.collectionView.contentOffset, .size = self.collectionView.bounds.size};
CGPoint visiblePoint = CGPointMake(CGRectGetMidX(visibleRect), CGRectGetMidY(visibleRect));
NSIndexPath *visibleIndexPath = [self.collectionView indexPathForItemAtPoint:visiblePoint];

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

সুইফ্ট সংস্করণ

let visibleRect = CGRect(origin: collectionView.contentOffset, size: collectionView.bounds.size)
let visiblePoint = CGPoint(x: visibleRect.midX, y: visibleRect.midY)
let visibleIndexPath = collectionView.indexPathForItem(at: visiblePoint)

9
আমি সম্মত হতে পারি, কখনও কখনও সূচিপথসফরভিজিবল আইটেমগুলি আরও বেশি কক্ষ ফিরিয়ে দেয়, এমনকি যদি আমরা মনে করি যে এরকম কেস না হওয়া উচিত। আপনার সমাধান দুর্দান্ত কাজ করে।
এমপি 23

2
আমি পুরোপুরি এই ধরণের পরিস্থিতিতে ছিলাম, কেবলমাত্র একটি ফিক্স যা আমার পক্ষে কাজ করেছিল (তবে আমার কেসটি টেবিলভিউ নিয়ে ছিল), আমাকে সিজিপয়েন্টম্যান (সিজিআরেক্টগেটমিডএক্স (ভিজ্যুয়ালেক্ট), সিজিআরেক্টগেটমিডওয়াই (দৃশ্যমান)) পরিবর্তন করা দরকার; সিজিপয়েন্টমনেকের (সিজিআরেক্টগেটমিডএক্স (দৃশ্যমান রেক্ট), সিজিআরেক্টগেটমিনি (দৃশ্যমান রেক্ট)) এর জন্য;
জেআরফেলএম

1
দুর্দান্ত, তবে যদি কোষগুলির মধ্যে একটি স্থান থাকে তবে visibleIndexPathকখনও কখনও শূন্য হয়ে যায়, সুতরাংif (visibleIndexPath) == nil { let cells = collectionView.visibleCells() let visibleIndexPath = collectionView.indexPathForCell(cells[0] as! UICollectionViewCell)! as NSIndexPath }
হুসাম

আমার সম্পূর্ণ পর্দার আকারের কক্ষগুলির জন্য একমাত্র সমাধানটি কাজ করেছে। নীচের উত্তর হিসাবে সুইফ্ট সংস্করণ যুক্ত হয়েছে।
স্যাম বিং

1
আমি আশা করি আমি এই আরও upvote করতে পারে। এই সমস্যাটি আমাকে বাদাম চালিয়ে চলেছে এবং এই সমাধানটি দিনটি বাঁচিয়েছে।
শান্ট

77

সুইফট 5 :

func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
    var visibleRect = CGRect()

    visibleRect.origin = collectionView.contentOffset
    visibleRect.size = collectionView.bounds.size

    let visiblePoint = CGPoint(x: visibleRect.midX, y: visibleRect.midY)

    guard let indexPath = collectionView.indexPathForItem(at: visiblePoint) else { return } 

    print(indexPath)
}

সুইফট ২.২-এ সংযুক্ত কাজের উত্তরসমূহ:

 func scrollViewDidEndDecelerating(scrollView: UIScrollView) {

        var visibleRect = CGRect()

        visibleRect.origin = self.collectionView.contentOffset
        visibleRect.size = self.collectionView.bounds.size

        let visiblePoint = CGPointMake(CGRectGetMidX(visibleRect), CGRectGetMidY(visibleRect))

        let visibleIndexPath: NSIndexPath = self.collectionView.indexPathForItemAtPoint(visiblePoint)

        guard let indexPath = visibleIndexPath else { return } 
        print(indexPath)

    }

দুইবার ইনডেক্সপথ পাওয়া, আমার একবারে পাওয়া দরকার
আরশাদ শাইক

18

সম্পূর্ণতার জন্য, এই পদ্ধতিটি আমার পক্ষে কাজ করে। এটি @ অ্যান্টনি এবং @ আইএনের পদ্ধতির সংমিশ্রণ ছিল।

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
      CGRect visibleRect = (CGRect){.origin = self.collectionView.contentOffset, .size = self.collectionView.bounds.size};
      CGPoint visiblePoint = CGPointMake(CGRectGetMidX(visibleRect), CGRectGetMidY(visibleRect));
      NSIndexPath *visibleIndexPath = [self.collectionView indexPathForItemAtPoint:visiblePoint];
      NSLog(@"%@",visibleIndexPath);
}

11

ইউ আই সি কালেকশনভিউডেলিগেট পদ্ধতিগুলি ব্যবহার করা সম্ভবত সেরা হবে: (সুইফ্ট 3)

// Called before the cell is displayed    
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
    print(indexPath.row)
}

// Called when the cell is displayed
func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
    print(indexPath.row)
}

3
সম্পর্কিত didEndDisplaying, দস্তাবেজগুলি থেকে: প্রতিনিধিটিকে বলুন যে নির্দিষ্ট ঘরটি সংগ্রহের ভিউ থেকে সরানো হয়েছিল। সংগ্রহটি ভিউ থেকে কোনও সেল কখন সরানো হবে তা সনাক্ত করতে এই পদ্ধতিটি ব্যবহার করুন, ভিউটি কখন অদৃশ্য হয়ে যায় তা দেখার জন্য তার বিপরীতে monitoring সুতরাং আমি মনে করি না যে didEndDisplayingকক্ষটি প্রদর্শিত হবে called
জনি

9

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

তাই আমি কিছু "বায়ু" দেওয়ার জন্য কোডটি প্রেরণ_অ্যাস্যাসিকের ভিতরে sertোকান এবং এটি আমার জন্য কাজ করে।

-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    dispatch_async(dispatch_get_main_queue(), ^{
            UICollectionViewCell * visibleCell= [[self.collectionView visibleCells] objectAtIndex:0];


            [visibleCell doSomthing];
        });
}

এটি সত্যিই সাহায্য করেছে! আমি বুঝতে পারিনি যে আমি একেবারে ত্রুটিহীন করতে প্রেরণ_চিন্তা ব্লক ব্যবহার করতে পারি! এটাই সেরা উত্তর!
কালাফুন

1
সুইফট 4-এর জন্য: DispatchQueue.main.async {কলটি যখন এমন func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
জনি

কিছু স্পষ্টতা: এটি আমাকেও সহায়তা করেছিল এবং ইউিকোলিকেশন ভিউযুক্ত ইউটিবেবলভিউতে স্ক্রোল করার সময় আমারও একই / অনুরূপ সমস্যা হয়েছিল। willDisplay cellউপরে উল্লেখ করা থেকে রিফ্রেশ কল শুরু হয়েছিল । আমি মনে করি, ইউআইকিট-এর কোথাও সমস্যাটি আমার জবাব হিসাবে সত্যিই একই।
জনি

7

সুইফট 3.0 এর জন্য

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    let visibleRect = CGRect(origin: colView.contentOffset, size: colView.bounds.size)
    let visiblePoint = CGPoint(x: visibleRect.midX, y: visibleRect.midY)
    let indexPath = colView.indexPathForItem(at: visiblePoint)
}

6

সুইফট 3.0

সহজ সমাধান যা আপনাকে দৃশ্যমান কক্ষগুলির জন্য সূচিপথ দেবে ..

yourCollectionView.indexPathsForVisibleItems 

সূচকপথের অ্যারে ফিরিয়ে দেবে।

এই জাতীয় অ্যারে থেকে প্রথম অবজেক্টটি নিন।

yourCollectionView.indexPathsForVisibleItems.first

আমার ধারণা এটি উদ্দেশ্য - সি হিসাবেও ঠিকভাবে কাজ করা উচিত।


6

ইউআইকোলিকেশনভিউ বর্তমান দৃশ্যমান সেল সূচক: সুইফট 3

var visibleCurrentCellIndexPath: IndexPath? {
    for cell in self.collectionView.visibleCells {
        let indexPath = self.collectionView.indexPath(for: cell)
        return indexPath
     }

     return nil
}

সর্বোত্তম উত্তর. পরিষ্কার এবং কয়েকটি লাইন।
গারান্ডা

1
নিখুঁত উত্তর .. আপনাকে ধন্যবাদ
হার্ডিক ঠাক্কর

3

অ্যান্টনির উত্তরটি সুইফট ৩.০ এ রূপান্তর করা আমার পক্ষে পুরোপুরি কাজ করেছে:

func scrollViewDidScroll(_ scrollView: UIScrollView) {

    var visibleRect = CGRect()
    visibleRect.origin = yourCollectionView.contentOffset
    visibleRect.size = yourCollectionView.bounds.size
    let visiblePoint = CGPoint(x: CGFloat(visibleRect.midX), y: CGFloat(visibleRect.midY))
    let visibleIndexPath: IndexPath? = yourCollectionView.indexPathForItem(at: visiblePoint)
    print("Visible cell's index is : \(visibleIndexPath?.row)!")
}

2

আপনি ব্যবহার করতে পারেন scrollViewDidEndDecelerating: এটির জন্য

//@property (strong, nonatomic) IBOutlet UICollectionView *collectionView;

   - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{

        for (UICollectionViewCell *cell in [self.collectionView visibleCells]) {
            NSIndexPath *indexPath = [self.collectionView indexPathForCell:cell];
            NSUInteger lastIndex = [indexPath indexAtPosition:[indexPath length] - 1];
            NSLog(@"visible cell value %d",lastIndex);
        }

    }

0

এটি পুরানো প্রশ্ন তবে আমার ক্ষেত্রে ...

- (void) scrollViewWillBeginDragging:(UIScrollView *)scrollView {

    _m_offsetIdx = [m_cv indexPathForCell:m_cv.visibleCells.firstObject].row;
}

- (void) scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    _m_offsetIdx = [m_cv indexPathForCell:m_cv.visibleCells.lastObject].row;
}

0

এছাড়াও এই স্নিপেট পরীক্ষা করে দেখুন

let isCellVisible = collectionView.visibleCells.map { collectionView.indexPath(for: $0) }.contains(inspectingIndexPath)

0

এই থ্রেডে, এমন অনেকগুলি সমাধান রয়েছে যা সেল পুরো স্ক্রিন গ্রহণ করলে ঠিকঠাক কাজ করে তবে তারা সংগ্রহ ভিউ সীমানা এবং দৃশ্যমান আয়তনের মিডপয়েন্টগুলি ব্যবহার করে তবে এই সমস্যার সহজ সমাধান আছে there

    DispatchQueue.main.async {
        let visibleCell = self.collImages.visibleCells.first
        print(self.collImages.indexPath(for: visibleCell))
    }

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


-1

এটি চেষ্টা করুন, এটি কাজ করে। (নীচের উদাহরণে আমার কাছে উদাহরণস্বরূপ 3 টি কোষ রয়েছে))

    func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
    let visibleRect = CGRect(origin: self.collectionView.contentOffset, size: self.collectionView.bounds.size)
    let visiblePoint = CGPointMake(CGRectGetMidX(visibleRect), CGRectGetMidY(visibleRect))
    let visibleIndexPath = self.collectionView.indexPathForItemAtPoint(visiblePoint)
    if let v = visibleIndexPath {
        switch v.item {
        case 0: setImageDescription()
            break
        case 1: setImageConditions()
            break
        case 2: setImageResults()
            break
        default: break
        }
    }

-2

সুইফট 3 এবং সুইফট 4:

func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
   var visibleRect = CGRect()

   visibleRect.origin = collectionView.contentOffset
   visibleRect.size = collectionView.bounds.size

   let visiblePoint = CGPoint(x: visibleRect.midX, y: visibleRect.midY)

   guard let indexPath = collectionView.indexPathForItem(at: visiblePoint) else { return } 

   print(indexPath[1])
}

আপনি যদি +1 যোগ করতে পারেন তার চেয়ে প্রকৃত সংখ্যাটি দেখাতে চান

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