ইউআইটিএবলভিউসেল সম্পূর্ণরূপে দৃশ্যমান কিনা তা যাচাই করার সেরা উপায়


100

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

এই মুহুর্তে দৃশ্যমান কক্ষগুলির তালিকার প্রতিটি কক্ষের মধ্যে আমি লুপ করছি, প্রতিবার দেখার জন্য স্ক্রোল করা থাকলে তা সম্পূর্ণরূপে দৃশ্যমান কিনা তা পরীক্ষা করে দেখছি। এটিই কি সেরা পন্থা?

আমার কোডটি এখানে:

- (void)scrollViewDidScroll:(UIScrollView *)aScrollView {

    CGPoint offset = aScrollView.contentOffset;
    CGRect bounds = aScrollView.bounds;    
    NSArray* cells = myTableView.visibleCells;

    for (MyCustomUITableViewCell* cell in cells) {

        if (cell.frame.origin.y > offset.y &&
            cell.frame.origin.y + cell.frame.size.height < offset.y + bounds.size.height) {

            [cell notifyCompletelyVisible];
        }
        else {

            [cell notifyNotCompletelyVisible];
        }
    }
}

সম্পাদনা করুন:

দয়া করে নোট করুন যে * - ( এনএসআর) দৃশ্যমান সেলগুলি দৃশ্যমান কোষগুলি প্রদান করে যা সম্পূর্ণ দৃশ্যমান এবং আংশিকভাবে দৃশ্যমান।

সম্পাদনা 2:

লনাফজিগার এবং ভাদিম ইয়েলগিন উভয়ের সমাধানের সংমিশ্রণের পরে এটিই সংশোধিত কোড :

- (void)scrollViewDidScroll:(UIScrollView *)aScrollView {
    NSArray* cells = myTableView.visibleCells;
    NSArray* indexPaths = myTableView.indexPathsForVisibleRows;

    NSUInteger cellCount = [cells count];

    if (cellCount == 0) return;

    // Check the visibility of the first cell
    [self checkVisibilityOfCell:[cells objectAtIndex:0] forIndexPath:[indexPaths objectAtIndex:0]];

    if (cellCount == 1) return;

    // Check the visibility of the last cell
    [self checkVisibilityOfCell:[cells lastObject] forIndexPath:[indexPaths lastObject]];

    if (cellCount == 2) return;

    // All of the rest of the cells are visible: Loop through the 2nd through n-1 cells
    for (NSUInteger i = 1; i < cellCount - 1; i++)
        [[cells objectAtIndex:i] notifyCellVisibleWithIsCompletelyVisible:YES];
}

- (void)checkVisibilityOfCell:(MultiQuestionTableViewCell *)cell forIndexPath:(NSIndexPath *)indexPath {
    CGRect cellRect = [myTableView rectForRowAtIndexPath:indexPath];
    cellRect = [myTableView convertRect:cellRect toView:myTableView.superview];
    BOOL completelyVisible = CGRectContainsRect(myTableView.frame, cellRect);

    [cell notifyCellVisibleWithIsCompletelyVisible:completelyVisible];
}

4
পার্শ্ব নোট হিসাবে, আপনার আগের সমস্ত প্রশ্নে যাওয়া উচিত এবং যারা আপনাকে সহায়তা করেছিল তাদের উত্তর গ্রহণ করা উচিত।
বাউব

4
আমাকে বলার জন্য ধন্যবাদ! আমি ইতিমধ্যে তাদের +1 দিয়েছি তবে সেট গৃহীত উত্তর বৈশিষ্ট্যটি ভুলে গিয়েছি।
রোহিনএনজেড 23'12

আপনার কোডটি আমার কাছে সঠিক দেখাচ্ছে এবং এটি জটিল হলেও এটি কার্যকর হয়। যা ভেঙে নেই তা ঠিক করবেন না, তাই না
কোডাফাই

উত্তর:


126

আপনি rectForRowAtIndexPath:পদ্ধতির সাথে কোনও ঘরের রেকট পেতে পারেন এবং এটি CGRectContainsRectফাংশন ব্যবহার করে টেবিলভিউয়ের সীমানা রেক্টের সাথে তুলনা করতে পারেন ।

মনে রাখবেন যে এটি কোষটি দৃশ্যমান না হলে এটি ইনস্ট্যান্ট করবে না এবং এভাবে দ্রুত হবে rather

সুইফট

let cellRect = tableView.rectForRowAtIndexPath(indexPath)
let completelyVisible = tableView.bounds.contains(cellRect)

ওবজ-সি

CGRect cellRect = [tableView rectForRowAtIndexPath:indexPath];
BOOL completelyVisible = CGRectContainsRect(tableView.bounds, cellRect);

অবশ্যই এটি কোনও তত্ত্বাবধানের দ্বারা টেবিলের ভিউ ক্লিপ করা বা অন্য দৃষ্টিতে অস্পষ্ট হওয়া বিবেচনা করবে না।


ধন্যবাদ! আমি এই কোডটি lnafziger এর সমাধানের সাথে সংযুক্ত করেছি।
রোহিনএনজেড 25'12

11
দ্বিতীয় CGRectContainsRect(tableView.bounds, [tableView rectForRowAtIndexPath:indexPath])
ভাবাতে

4
কেন এটি আমার সেলরেক্টের উত্স? x = 0, উত্স.y = 0, প্রস্থ = 0, উচ্চতা = 0? যদিও ইউআইতে তারা সমস্ত 0 টি নয়, আমি অটো লেআউট ব্যবহার করছি, কোনও ধারণা?
রেইনকাস্ট

7
সুইফট 3:let completelyVisible = tableView.bounds.contains(tableView.rectForRow(at: indexPath))
সিবারটেল

আমরা কীভাবে ইউআইকোলিকেশনভিউয়ের জন্য একই কার্যকারিতা পরিচালনা করতে পারি?
সত্যম

64

আমি এটি এইভাবে পরিবর্তন করব:

- (void)checkVisibilityOfCell:(MyCustomUITableViewCell *)cell inScrollView:(UIScrollView *)aScrollView {
    CGRect cellRect = [aScrollView convertRect:cell.frame toView:aScrollView.superview];

    if (CGRectContainsRect(aScrollView.frame, cellRect))
        [cell notifyCompletelyVisible];
    else
        [cell notifyNotCompletelyVisible];
}

- (void)scrollViewDidScroll:(UIScrollView *)aScrollView { 
    NSArray* cells = myTableView.visibleCells;

    NSUInteger cellCount = [cells count];
    if (cellCount == 0)
        return;

    // Check the visibility of the first cell
    [self checkVisibilityOfCell:[cells firstObject] inScrollView:aScrollView];
    if (cellCount == 1)
        return;

    // Check the visibility of the last cell
    [self checkVisibilityOfCell:[cells lastObject] inScrollView:aScrollView];
    if (cellCount == 2)
        return;

    // All of the rest of the cells are visible: Loop through the 2nd through n-1 cells
    for (NSUInteger i = 1; i < cellCount - 1; i++)
        [[cells objectAtIndex:i] notifyCompletelyVisible];
}

যদি বিবৃতিতে <এবং> << বা> = হওয়া উচিত, আমি উত্তরে এটি সংশোধন করব ...
আর্দভার্ক

12

কত শতাংশ দৃশ্যমান তা দেখতে আপনি এই জাতীয় কিছু চেষ্টা করতে পারেন:

-(void)scrollViewDidScroll:(UIScrollView *)sender
{
    [self checkWhichVideoToEnable];
}

-(void)checkWhichVideoToEnable
{
    for(UITableViewCell *cell in [tblMessages visibleCells])
    {
        if([cell isKindOfClass:[VideoMessageCell class]])
        {
            NSIndexPath *indexPath = [tblMessages indexPathForCell:cell];
            CGRect cellRect = [tblMessages rectForRowAtIndexPath:indexPath];
            UIView *superview = tblMessages.superview;

            CGRect convertedRect=[tblMessages convertRect:cellRect toView:superview];
            CGRect intersect = CGRectIntersection(tblMessages.frame, convertedRect);
            float visibleHeight = CGRectGetHeight(intersect);

            if(visibleHeight>VIDEO_CELL_SIZE*0.6) // only if 60% of the cell is visible
            {
                // unmute the video if we can see at least half of the cell
                [((VideoMessageCell*)cell) muteVideo:!btnMuteVideos.selected];
            }
            else
            {
                // mute the other video cells that are not visible
                [((VideoMessageCell*)cell) muteVideo:YES];
            }
        }
    }
}

যদি টেবিল ভিউ ভিডিও সহ 2 টি কক্ষ প্রদর্শন করতে সক্ষম হয় (উদাহরণস্বরূপ আইপ্যাডে), উভয় ভিডিও উপরের কোডটি দিয়ে খেলবে?
জেরোম

@ ক্যাটালিন আমি আপনার সমাধানটি চেষ্টা করেছি তবে আমার টেবিলভিউটি মন্দা হয়ে যায়। স্ক্রোলিং পারফরমেন্স উন্নত করার কোনও উপায়?
রাহুল ব্যাস

@ রাহুলভিয়াস দুঃখিত কিন্তু না :( আপনার অভ্যন্তরীণ উপাদানগুলি পরীক্ষা করুন সম্ভবত স্তর /
সাবলেয়ারদের সাথে সম্পর্কিত

5

ডক্স থেকে:

দৃশ্যমান সেলগুলি রিসিভারে দৃশ্যমান সারণী কক্ষগুলি ফিরিয়ে দেয়।

- (NSArray *)visibleCells

রিটার্ন মান UITableViewCell অবজেক্ট সমন্বিত একটি অ্যারে, প্রত্যেকে প্রাপ্ত টেবিল ভিউতে দৃশ্যমান কক্ষকে উপস্থাপন করে।

আইওএস ২.০ এবং তারপরে উপলভ্যতা উপলব্ধ।

আরও দেখুন - সূচিপথগুলিভিজিবলরো


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

5

আপনি যদি সামগ্রীটি ইনসেটটিকে অ্যাকাউন্টে নিতে চান এবং কোনও সুপারভিউয়ের উপর নির্ভর করতে না চান (সুপারভিউতে টেবিল ভিউ ফ্রেম 0,0 এর বাইরে অন্য কিছু হতে পারে), তবে এখানে আমার সমাধানটি দেওয়া হয়েছে:

extension UITableView {

    public var boundsWithoutInset: CGRect {
        var boundsWithoutInset = bounds
        boundsWithoutInset.origin.y += contentInset.top
        boundsWithoutInset.size.height -= contentInset.top + contentInset.bottom
        return boundsWithoutInset
    }

    public func isRowCompletelyVisible(at indexPath: IndexPath) -> Bool {
        let rect = rectForRow(at: indexPath)
        return boundsWithoutInset.contains(rect)
    }
}


0
UICollectionViewCell *cell = [self.collectionView cellForItemAtIndexPath:indexPath];
CGRect frame = cell.frame;
if (CGRectContainsRect(CGRectOffset(self.collectionView.frame, self.collectionView.contentOffset.x, self.collectionView.contentOffset.y), frame))
{
    // is on screen
}

0

এমনকি আপনি যদি বলেন যে আপনি যতবার স্ক্রোল করেছেন ততবার আপনি এটি পরীক্ষা করতে চান, আপনি এটিও ব্যবহার করতে পারেন

-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
       CGRect cellRect = [tableView convertRect:cell.frame toView:tableView.superview];
       if (CGRectContainsRect(tableView.frame, cellRect)){
            //Do things in case cell is fully displayed
        }

}

0

সম্ভবত এই ইস্যুটির জন্য ইউআইটিএবলভিউডেলিগেটের পরবর্তী ফাংশনটি আরও ভাল ব্যবহার করা যেতে পারে

func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath)

এটি কাজ করবে না। একটি ডক থেকেtells the delegate that the specified cell was removed from the table.
anatoliy_v

0

নীচের কোডটি আপনাকে সংগ্রহের ভিউয়ের লেআউট বৈশিষ্ট্যের মাধ্যমে কোনও সংগ্রহ ভিউ সেলটি সম্পূর্ণরূপে দৃশ্যমান কিনা তা পরীক্ষা করতে দেয়।

guard let cellRect = collectionView.layoutAttributesForItem(at: indexPath)?.frame else { return } let isCellCompletelyVisible = collectionView.bounds.contains(cellRect)

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