ইউআইআরআইফ্রেসকন্ট্রোল - ইউআইটিএবল ভিউকন্ট্রোলার ইউআইএনএভিগেশন কন্ট্রোলারের অভ্যন্তরে থাকাকালীন নতুন কাজ শুরু করছে না


120

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

[self.refreshControl beginRefreshing];

কিছুই ঘটেনি. এটি স্পষ্টরকে প্রাণবন্ত করে তুলতে হবে। দ্যendRefreshingপদ্ধতি সঠিকভাবে কাজ করে যখন আমি রিফ্রেশ পর যে কল।

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

self.viewController = tableViewController;
self.window.rootViewController = self.viewController;

তবে আমি যদি tableViewControllerপ্রথমে কোনও ইউআইএনএভিগেশন কন্ট্রোলারটিতে যোগ করি তবে তারপরে নেভিগেশন কন্ট্রোলারটি যুক্ত করুন rootViewController, beginRefreshingপদ্ধতিটি আর কাজ করে না। যেমন

UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:tableViewController];
self.viewController = navController;
self.window.rootViewController = self.viewController;

আমার অনুভূতি হ'ল নেভিগেশন কন্ট্রোলারের অভ্যন্তরের নেস্টেড ভিউয়ের স্তরবিন্যাসের সাথে রিফ্রেশার নিয়ন্ত্রণের সাথে ভাল খেলছে না - এর সাথে কোনও পরামর্শ?

ধন্যবাদ

উত্তর:


195

দেখে মনে হচ্ছে আপনি যদি প্রোগ্রামিয়ালি রিফ্রেশ শুরু করেন, আপনাকে টেবিলটি নিজে স্ক্রোল করতে হবে, কনটেন্ট অফসেট পরিবর্তন করে বলুন

[self.tableView setContentOffset:CGPointMake(0, -self.refreshControl.frame.size.height) animated:YES];

আমি এর কারণটি অনুমান করব যে ব্যবহারকারী যখন সারণী দর্শনটির মাঝখানে / নীচে থাকে তখন রিফ্রেশ নিয়ন্ত্রণে স্ক্রোল করা অযাচিত হতে পারে?

@Muhasturk দ্বারা সুইফট ২.২ সংস্করণ

self.tableView.setContentOffset(CGPoint(x: 0, y: -refreshControl.frame.size.height), animated: true)

সংক্ষেপে, এই পোর্টেবল রাখতে এই এক্সটেনশনটি যুক্ত করুন

UIRefreshControl + + ProgramaticallyBeginRefresh.swift

extension UIRefreshControl {
    func programaticallyBeginRefreshing(in tableView: UITableView) {
        beginRefreshing()
        let offsetPoint = CGPoint.init(x: 0, y: -frame.size.height)
        tableView.setContentOffset(offsetPoint, animated: true)        
    }
}

6
এটা অদ্ভুত, আমার পরীক্ষায়, রিফ্রেশিং প্রয়োজন অনুসারে অফসেট সামঞ্জস্য করে
দিমিত্রি শেভচেঙ্কো

9
বিটিডাব্লু, আপনি যদি অটো লেআউট ব্যবহার করছেন তবে আপনি উত্তরের সাথে লাইনটি প্রতিস্থাপন করতে পারেন: [সেল্ফ.ট্যাটিভিউ সেটকন্টেন্টঅফসেট: সিজিপয়েন্টমনেক (0,-self.topLayoutGuide.length) অ্যানিমেটেড: YES];
এরিক বেকার

4
@ এরিকবেকার আমি বিশ্বাস করি যে এটি করবে না। সমস্ত UITableViewControllers নেভিগেশন বার দেখায় না show এটি দৈর্ঘ্যের 20 এর শীর্ষস্থানীয় লেআউটগাইড এবং একটি অফসেট খুব ছোট করে নিয়ে যাবে।
ফ্যাবিও অলিভিরা

3
@ এরিকব্যাকার আপনি ব্যবহার করতে পারেন: [সেল্ফ.ট্যাবলভিউ সেটকন্টেন্টঅফসেট: সিজিপিয়েন্টম্যান্ট (0, সেলফি.টেলআউটলাইউড.লাইনেথ: সেলফ্রেস কন্ট্রোল.ফ্রেম.সাইজ.হাইট) অ্যানিমেটেড: হ্যাঁ];
ZYiOS

1
কপি পেস্ট আমার জন্য কাজ করে যা দুর্দান্ত। আমি অ্যাপলের স্টোরিবোর্ড নির্মাতারা জিনিসগুলি পেয়ে ক্লান্ত হয়ে পড়ছিলাম।
Okysabeni

78

ইউআইটিএবলভিউকন্ট্রোলারের স্বয়ংক্রিয়ভাবে অ্যাডজাস্টসস্ক্রোলভিউআইনসেটস রয়েছে আইওএস after এর পরে বৈশিষ্ট্যযুক্ত The

সুতরাং প্রোগ্রামিংভাবে রিফ্রেশ শুরু করার পরে রিফ্রেশকন্ট্রোল দেখানোর সঠিক উপায়টি বিদ্যমান কন্টেন্টঅফসেটে রিফ্রেশকন্ট্রোলের উচ্চতা যুক্ত করছে।

 [self.refreshControl beginRefreshing];
 [self.tableView setContentOffset:CGPointMake(0, self.tableView.contentOffset.y-self.refreshControl.frame.size.height) animated:YES];

হাই, আপনাকে অনেক ধন্যবাদ, আমি ডিবাগ করার সময় যে ম্যাজিক পয়েন্টটি দেখতে পেয়েছিলাম (0, -64) সে সম্পর্কে আমিও আগ্রহী।
ইনিক্স

2
নেভিগেশন বারের উচ্চতার জন্য স্ট্যাটাস বারের উচ্চতা + 44 এর জন্য @ ইনিক্স 20
ইগোটিট

1
পরিবর্তে -64ব্যবহার করা ভাল-self.topLayoutGuide.length
Diogo T

33

উপরে বর্ণিত কৌশলগুলি ব্যবহার করে এখানে একটি সুইফট এক্সটেনশন।

extension UIRefreshControl {
    func beginRefreshingManually() {
        if let scrollView = superview as? UIScrollView {
            scrollView.setContentOffset(CGPoint(x: 0, y: scrollView.contentOffset.y - frame.height), animated: true)
        }
        beginRefreshing()
    }
}

ইউআইটিএবলভিউয়ের জন্য কাজ করে।
হুয়ান বোয়েরো

10
আমি sendActionsForControlEvents(UIControlEvents.ValueChanged)এই ফাংশনটির শেষে রাখার পরামর্শ দেব , অন্যথায় আসল রিফ্রেশ লজিক যুক্তিটি চালানো হবে না।
কলিন বাসনেট

এটি এটি করার জন্য এখন পর্যন্ত সবচেয়ে মার্জিত উপায়। উন্নত কার্যকারিতার জন্য কলিন বাসনেটের মন্তব্য সহ। এটি একবারে সংজ্ঞায়িত করে এটি পুরো প্রকল্প জুড়ে ব্যবহার করা যেতে পারে!
জো গ্যালিন্ড

1
@ কলিনব্যাসনেট: সেই কোডটি যুক্ত করা (যা এখন প্রেরণিকরণ (যার জন্য: ইউআইসিএন্ট্রোলটেন্টস: মূল্যায়ন বদলানো)) ফলাফল অসীম লুপে পরিণত হয় ...
কেন্ডাল হেলস্টেটার জেলনার

15

অন্য কোনও উত্তর আমার পক্ষে কাজ করেনি। তারা স্পিনারকে দেখাতে এবং স্পিন করার কারণ ঘটায় তবে রিফ্রেশ অ্যাকশন নিজেই কখনও ঘটবে না। এইটা কাজ করে:

id target = self;
SEL selector = @selector(example);
// Assuming at some point prior to triggering the refresh, you call the following line:
[self.refreshControl addTarget:target action:selector forControlEvents:UIControlEventValueChanged];

// This line makes the spinner start spinning
[self.refreshControl beginRefreshing];
// This line makes the spinner visible by pushing the table view/collection view down
[self.tableView setContentOffset:CGPointMake(0, -1.0f * self.refreshControl.frame.size.height) animated:YES];
// This line is what actually triggers the refresh action/selector
[self.refreshControl sendActionsForControlEvents:UIControlEventValueChanged];

দ্রষ্টব্য, এই উদাহরণটি একটি সারণী দর্শন ব্যবহার করে তবে এটি সংগ্রহের দৃশ্যও হতে পারে।


এটি আমার সমস্যার সমাধান করেছে। তবে এখন আমি ব্যবহার করছি SVPullToRefresh, এটি প্রোগ্রামিয়ালি কীভাবে টেনে আনব?
গাঙ্ক

1
@ গ্যাঙ্ক আমি কখনও এসভিপুলটোরোফ্রেস ব্যবহার করি নি। আপনি কি তাদের ডক্স পড়ার চেষ্টা করেছেন? এটি ডকসের উপর ভিত্তি করে একেবারে সুস্পষ্ট বলে মনে হচ্ছে যে এটি প্রোগ্রামেমেটিকভাবে টেনে নামানো যেতে পারে: "আপনি যদি প্রোগ্রামিকভাবে রিফ্রেশটি ট্রিগার করতে চান (উদাহরণস্বরূপ ভিউডিডঅ্যাপারে :), আপনি এটি দিয়ে এটি করতে পারেন: [tableView triggerPullToRefresh];" দেখুন: github.com/samvermette/ এসভিপুলটোরোফ্রেশ
কাইল রবসন

1
পারফেক্ট! যদিও এটি অ্যানিমেশন দিয়ে আমার জন্য অদ্ভুত অভিনয় করছিল, তাই আমি কেবল এটির সাথে প্রতিস্থাপন করেছিscrollView.contentOffset = CGPoint(x: 0, y: scrollView.contentOffset.y - frame.height)
ব্যবহারকারী 1366265

13

ইতিমধ্যে উল্লিখিত পদ্ধতি:

[self.refreshControl beginRefreshing];
 [self.tableView setContentOffset:CGPointMake(0, self.tableView.contentOffset.y-self.refreshControl.frame.size.height) animated:YES];

স্পিনার দৃশ্যমান করা হবে। তবে তা প্রাণবন্ত হবে না। আমি যে জিনিসটি পরিবর্তন করেছি তা হ'ল এই দুটি পদ্ধতির ক্রম এবং সমস্ত কিছু কাজ করেছে:

[self.tableView setContentOffset:CGPointMake(0, self.tableView.contentOffset.y-self.refreshControl.frame.size.height) animated:YES];
[self.refreshControl beginRefreshing];

11

সুইফ্ট 4 / 4.1 এর জন্য

বিদ্যমান উত্তরের মিশ্রণটি আমার পক্ষে কাজটি করে:

refreshControl.beginRefreshing()
tableView.setContentOffset(CGPoint(x: 0, y: tableView.contentOffset.y - (refreshControl.frame.size.height)), animated: true)

আশাকরি এটা সাহায্য করবে!


7

এই প্রশ্নটি দেখুন

ইউআরআইফ্রেসকন্ট্রোল শুরুর দিকে কল করার সময় চতুর দেখাচ্ছেন না রিফ্রেশিং এবং কন্টেন্টঅফসেটটি 0 হয়

এটি আমার কাছে একটি বাগের মতো দেখাচ্ছে কারণ এটি কেবল তখনই ঘটে যখন টেবিলভিউয়ের সামগ্রীঅফসেট সম্পত্তি 0 হয়

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

- (void)beginRefreshingTableView {

    [self.refreshControl beginRefreshing];

    if (self.tableView.contentOffset.y == 0) {

        [UIView animateWithDuration:0.25 delay:0 options:UIViewAnimationOptionBeginFromCurrentState animations:^(void){

            self.tableView.contentOffset = CGPointMake(0, -self.refreshControl.frame.size.height);

        } completion:^(BOOL finished){

        }];

    }
}

1
এটি সত্য নয়, আমার দুটি ভিন্ন ইউআইভিউ কনট্রোলার রয়েছে যার উভয়ই ভিডিডলয়েডের উপর 0 এর একটি কনটেন্ট অফসেট রয়েছে এবং তাদের মধ্যে একটি [স্বতঃআরফ্রেশকন্ট্রোল শুরু রিফ্রেশিং] কল করার পরে রিফ্রেশকন্ট্রলটি সঠিকভাবে নীচে টেনে নেয় এবং অন্যটি না করে: /
সিমোনথাম্পার

ডকুমেন্টেশন নিয়ন্ত্রণ প্রদর্শন প্রদর্শন সম্পর্কে কিছুই বলে না beginRefreshing, কেবলমাত্র তার রাষ্ট্র পরিবর্তন করে। আমি এটি দেখতে পাচ্ছি, এটি পুনরায় রিফ্রেশ ক্রিয়াকলাপটি শুরু করা বাধা দেওয়া, যাতে কোনও প্রোগ্রামিকভাবে রিফ্রেশ নামে পরিচিত এটি এখনও চালু থাকবে, কোনও ব্যবহারকারী সূচিত ক্রিয়াটি আরম্ভ করবে না start
কোয়েন

আমি সেট কনটেন্ট অফসেট: অ্যানিমেটেড পদ্ধতি ব্যবহার করে সমস্যাগুলি লক্ষ করেছি so সুতরাং এই সমাধানটি আমার পক্ষে কাজ করেছে।
মার্ক এচেভারি

7

এখানে সুইফট 3 এবং পরের এক্সটেনশানটি স্পিনারের পাশাপাশি এনিমেট দেখায়।

import UIKit
extension UIRefreshControl {

func beginRefreshingWithAnimation() {

    DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) {

        if let scrollView = self.superview as? UIScrollView {
            scrollView.setContentOffset(CGPoint(x: 0, y: scrollView.contentOffset.y - self.frame.height), animated: true)
          }
        self.beginRefreshing()
      }
   }
}

2
উপরের সমস্ত উত্তরগুলির মধ্যে, আমি কেবলমাত্র iOS 11.1 /
এক্সকোড

1
asyncAfterআসলে স্পিনার অ্যানিমেশন কাজ করে তোলে কি (10.2 আইওএস 12.3 / Xcode) হল
francybiga

4

এটি আমার পক্ষে নিখুঁত কাজ করেছে:

সুইফট 3:

self.tableView.setContentOffset(CGPoint(x: 0, y: -self.refreshControl!.frame.size.height - self.topLayoutGuide.length), animated: true)

4

সুইফ্ট 5 এর জন্য, আমার কাছে কেবল কল করা ছিল না refreshControl.sendActions(.valueChanged)। এটিকে আরও পরিষ্কার করার জন্য আমি একটি এক্সটেনশন করেছি।

extension UIRefreshControl {

    func beginRefreshingManually() {
        if let scrollView = superview as? UIScrollView {
            scrollView.setContentOffset(CGPoint(x: 0, y: scrollView.contentOffset.y - frame.height), animated: false)
        }
        beginRefreshing()
        sendActions(for: .valueChanged)
    }

}

3

@ দিমিত্রি শেভচেঙ্কো সমাধান ছাড়াও।

আমি এই ইস্যুতে সুন্দর কাজ পেয়েছি। আপনি UIRefreshControlসেই ওভাররাইট পদ্ধতিতে এক্সটেনশন তৈরি করতে পারেন :

// Adds code forgotten by Apple, that changes content offset of parent scroll view (table view).
- (void)beginRefreshing
{
    [super beginRefreshing];

    if ([self.superview isKindOfClass:[UIScrollView class]]) {
        UIScrollView *view = (UIScrollView *)self.superview;
        [view setContentOffset:CGPointMake(0, view.contentOffset.y - self.frame.size.height) animated:YES];
    }
}

ইন্টারফেস বিল্ডারে রিফ্রেশ নিয়ন্ত্রণের জন্য আপনি পরিচয় পরিদর্শকটিতে কাস্টম ক্লাস সেট করে নতুন ক্লাস ব্যবহার করতে পারেন ।


3

ফোর্ট সুইফট 2.2+ +

    self.tableView.setContentOffset(CGPoint(x: 0, y: -refreshControl.frame.size.height), animated: true)

আমি এটি গ্রহণযোগ্য উত্তরের সাথে একীভূত করেছি কারণ এটি কেবলমাত্র একটি আপডেট।
টিউডর

3

আপনি যদি সুইট ৩.১-এর জন্য আরএক্সসউইফ্ট ব্যবহার করেন তবে নীচে ব্যবহার করতে পারেন:

func manualRefresh() {
    if let refreshControl = self.tableView.refreshControl {
        self.tableView.setContentOffset(CGPoint(x: 0, y: -refreshControl.height), animated: true)
        self.tableView.refreshControl?.beginRefreshing()
        self.tableView.refreshControl?.sendActions(for: .valueChanged)
    }
}

এই সুইফট 3.1, আইওএস 10 এর জন্য কাজ করে।


1
তার sendActionsট্রিগার rxযে এর সাথে সম্পর্কিত এই উত্তরটি তোলে RxSwiftআধারস্থ যে কেউ প্রথম বর্ণন হতাশ হয়
carbonr

আমাকে টেবিলভিউ নয়, টেবিল ভিউ কনট্রোলার থেকে রিফ্রেশকন্ট্রোল উদাহরণটি ব্যবহার করতে হয়েছিল। এছাড়াও, সেই সেটকন্টেন্ট অফসটি আইওএস 10 লক্ষ্য করে আমার পক্ষে কাজ করে নি। এটি অবশ্য কাজ করে: self.tableView.setContentOffset(CGPoint(x:0, y:self.tableView.contentOffset.y - (refreshControl.frame.size.height)), animated: true)
এনএমডিয়াস

1

সুইফ্ট 5 এ পরীক্ষা করা হয়েছে

এটি ব্যবহার করুন viewDidLoad()

fileprivate func showRefreshLoader() {
    DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) {
        self.tableView.setContentOffset(CGPoint(x: 0, y: self.tableView.contentOffset.y - (self.refreshControl.frame.size.height)), animated: true)
        self.refreshControl.beginRefreshing() 
    }
}

0

আমি প্রদর্শন ব্যবহারকারী "ডেটা আপডেট" ভিজ্যুয়াল সাইন জন্য একই কৌশল ব্যবহার করি। একটি ফলাফল ব্যবহারকারী ব্যাকগ্রাউন্ড থেকে অ্যাপ আনবে এবং ফিড / তালিকাগুলি ইউআই সহ আপডেট হবে যেমন ব্যবহারকারীরা নিজেকে রিফ্রেশ করার জন্য টেবিল টানেন। আমার সংস্করণে 3 টি জিনিস রয়েছে

1) "জেগে উঠুন" কে পাঠায়

- (void)applicationDidBecomeActive:(UIApplication *)application {
    [[NSNotificationCenter defaultCenter] postNotificationName:kNotificationHaveToResetAllPages object:nil];
}

2) ইউআইভিউকন্ট্রোলারে পর্যবেক্ষক

- (void)viewDidLoad {
    [super viewDidLoad];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(forceUpdateData) name:kNotificationHaveToWakeUp:nil];
}

3) প্রোটোকল

#pragma mark - ForcedDataUpdateProtocol

- (void)forceUpdateData {
    self.tableView.contentOffset = CGPointZero;

    if (self.refreshControl) {
        [self.refreshControl beginRefreshing];
        [self.tableView setContentOffset:CGPointMake(0, -self.refreshControl.frame.size.height) animated:YES];
        [self.refreshControl performSelector:@selector(endRefreshing) withObject:nil afterDelay:1];
    }
}

ফলাফল

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