objective-c - UITefreshControl UITableViewController के बिना




ios ios6 uirefreshcontrol (11)

बस जिज्ञासा है, क्योंकि यह तुरंत संभव नहीं लगता है, लेकिन क्या UITableViewController subclass का उपयोग किये बिना नए आईओएस 6 UIRefreshControl क्लास का लाभ उठाने का कोई UIRefreshControl तरीका है?

मैं अक्सर UIViewController उपयोग UITableView UIViewController साथ करता हूं और UITableViewDataSource और UITableViewDelegate अनुरूप एक UITableViewController का उपयोग करने के बजाय।


Answers

एक झुकाव पर, और ड्रमरबी की प्रेरणा के आधार पर, मैंने अपने UITableView UIRefreshControl रूप में बस एक UIRefreshControl इंस्टेंस जोड़ने की कोशिश की। और यह जादूगर बस काम करता है!

UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
[refreshControl addTarget:self action:@selector(handleRefresh:) forControlEvents:UIControlEventValueChanged];
[self.myTableView addSubview:refreshControl];

यह आपके टेबल व्यू के ऊपर एक UIRefreshControl जोड़ता है और UITableViewController का उपयोग किये बिना अपेक्षित काम करता है :)

संपादित करें: यह उपर्युक्त काम करता है लेकिन कुछ लोगों ने बताया है कि इस तरह से यूआईआरआईफ्रेश कंट्रोल जोड़ते समय थोड़ा सा "स्टटर" होता है। इसका समाधान एक UITableViewController को चालू करना है, और फिर उस पर अपना यूआईआरफ़्रेश कंट्रोल और UITableView सेट करना है, यानी:

UITableViewController *tableViewController = [[UITableViewController alloc] init];
tableViewController.tableView = self.myTableView;

self.refreshControl = [[UIRefreshControl alloc] init];
[self.refreshControl addTarget:self action:@selector(getConnections) forControlEvents:UIControlEventValueChanged];
tableViewController.refreshControl = self.refreshControl;

स्वीकृत उत्तर के कारण होने वाले स्टटर को खत्म करने के लिए, आप अपने UITableView को UITableView पर असाइन कर सकते हैं।

_tableViewController = [[UITableViewController alloc]initWithStyle:UITableViewStylePlain];
[self addChildViewController:_tableViewController];

_tableViewController.refreshControl = [UIRefreshControl new];
[_tableViewController.refreshControl addTarget:self action:@selector(loadStream) forControlEvents:UIControlEventValueChanged];

_theTableView = _tableViewController.tableView;

संपादित करें:

बिना UIRefreshControl के बिना UIRefreshControl जोड़ने का कोई तरीका नहीं है और UIRefreshControl पर डेटा को ताज़ा करने के बाद अच्छी एनीमेशन बनाए रखें।

UIRefreshControl *refreshControl = [UIRefreshControl new];
[refreshControl addTarget:self action:@selector(handleRefresh:) forControlEvents:UIControlEventValueChanged];
[self.theTableView addSubview:refreshControl];
[self.theTableView sendSubviewToBack:refreshControl];

बाद में ताज़ा डेटा को संभालने पर ...

- (void)handleRefresh:(UIRefreshControl *)refreshControl {
    [self.theTableView reloadData];
    [self.theTableView layoutIfNeeded];
    [refreshControl endRefreshing];
}

यह पता चला है कि आप UIViewCiewroller का उपयोग UITableView सबव्यू के साथ करते हैं और UITableViewDataSource और UITableViewDelegate के अनुरूप करते हैं, तो आप निम्न का उपयोग कर सकते हैं:

self.refreshControl = [[UIRefreshControl alloc]init];
[self.refreshControl addTarget:self action:@selector(refresh:) forControlEvents:UIControlEventValueChanged];

-endRefresh बाद एक सेकंड के अंश द्वारा रीफ्रेश -endRefresh -ेंड -endRefresh विधि को कॉल में देरी करने का प्रयास करें, एनएसओब्जेक्ट्स -परफॉर्म -endRefresh का उपयोग करके, या तो इसके सामग्री को फिर से लोड करता है -performSelector:withObject:afterDelay: या जीसीडी का dispatch_after

मैंने इसके लिए UIRefreshControl पर एक श्रेणी बनाई:

@implementation UIRefreshControl (Delay)

- (void)endRefreshingAfterDelay:(NSTimeInterval)delay {
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delay * NSEC_PER_SEC));
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
        [self endRefreshing];
    });
}

@end

मैंने इसका परीक्षण किया और यह संग्रह दृश्यों पर भी काम करता है। मैंने देखा है कि 0.01 सेकेंड जितना छोटा विलंब पर्याप्त है:

// My data refresh process here while the refresh control 'isRefreshing'
[self.tableView reloadData];
[self.refreshControl endRefreshingAfterDelay:.01];

इसे इस्तेमाल करे,

उपरोक्त समाधान ठीक हैं लेकिन tableView.refreshControl केवल आईओएस 9 एक्स तक यूआईटीबल व्यू कंट्रोलर के लिए उपलब्ध है और आईओएस 10.x से यूआईटीबल व्यू में आता है।

स्विफ्ट 3 में लिखा है -

let refreshControl = UIRefreshControl()
refreshControl.addTarget(self, action: #selector(FeedViewController.loadNewData), for: UIControlEvents.valueChanged)
// Fix for the RefreshControl Not appearing in background
tableView?.addSubview(refreshControl)
tableView.sendSubview(toBack: refreshControl)

यहां एक और समाधान है जो थोड़ा अलग है।

मुझे इसका उपयोग कुछ दृश्य पदानुक्रम के मुद्दों के कारण करना था: मैं कुछ कार्यक्षमता बना रहा था जिसमें दृश्य पदानुक्रम में विभिन्न स्थानों के आस-पास के दृश्यों की आवश्यकता होती थी, जो UITableViewController के tableview b / c तालिका का उपयोग करते समय टूटा हुआ दृश्य दृश्य UITableViewController का रूट व्यू है ( self.view) और न केवल एक नियमित दृश्य, यह असंगत नियंत्रक / पदानुक्रमों को देखा और एक दुर्घटना का कारण बन गया।

मूल रूप से UITableViewController का अपना उप-वर्ग बनाएं और स्वयं को असाइन करने के लिए loadView ओवरराइड करें। एक अलग दृश्य देखें, और तालिका को ओवरराइड करें एक अलग टेबलव्यू वापस करने के लिए प्रॉपर्टी देखें।

उदाहरण के लिए:

@interface MyTableVC : UITableViewController
@end

@interface MyTableVC ()
@property (nonatomic, strong) UITableView *separateTableView;
@end

@implementation MyTableVC

- (void)loadView {
    self.view = [[UIView alloc] initWithFrame:CGRectZero];
}

- (UITableView *)tableView {
    return self.separateTableView;
}

- (void)setTableView:(UITableView *)tableView {
    self.separateTableView = tableView;
}

@end

केलर के समाधान के साथ संयुक्त होने पर यह इस अर्थ में और अधिक मजबूत होगा कि तालिका दृश्य अब नियमित दृश्य है, वीसी के रूट व्यू नहीं, और दृश्य पदानुक्रमों को बदलने के खिलाफ और अधिक मजबूत हो। इस तरह इसका उपयोग करने का उदाहरण:

MyTableVC *tableViewController = [[MyTableVC alloc] init];
tableViewController.tableView = self.myTableView;

self.refreshControl = [[UIRefreshControl alloc] init];
[self.refreshControl addTarget:self action:@selector(getConnections) forControlEvents:UIControlEventValueChanged];
tableViewController.refreshControl = self.refreshControl;

इसके लिए एक और संभावित उपयोग है:

चूंकि इस तरह से subclassing self.tableView से self.view को अलग करता है, अब यह UITableViewController को नियमित नियंत्रक के रूप में उपयोग करना संभव है, और UITableView में सबव्यूव्यू जोड़ने की विषमताओं के बिना स्वयं .view में अन्य सबव्यूव्स जोड़ें, इसलिए कोई भी उन्हें बनाने पर विचार कर सकता है UITableViewController बच्चों को रखने के बजाय नियंत्रकों को सीधे UITableViewController का उप-वर्ग देखें।

कुछ चीजों को देखने के लिए:

चूंकि हम तालिका को ओवरराइड कर रहे हैं सुपर को कॉल किए बिना देखें, वहां कुछ चीजें देखने के लिए हो सकती हैं और जहां आवश्यक हो, उन्हें संभालना चाहिए। उदाहरण के लिए, मेरे उपर्युक्त उदाहरण में टेबलव्यू सेट करने से स्वयं कोव्यूव में टेबलव्यू नहीं जोड़ा जाएगा और फ्रेम को सेट नहीं किया जा सकता है जिसे आप करना चाहते हैं। साथ ही, इस कार्यान्वयन में कक्षा को तत्काल होने पर आपको कोई डिफ़ॉल्ट तालिका दिखाई नहीं दी जाती है, जो कुछ भी आप जोड़ सकते हैं। मैं इसे यहां शामिल नहीं करता क्योंकि यह मामला मामला है, और यह समाधान वास्तव में केलर के समाधान के साथ फिट बैठता है।


स्विफ्ट 2.2 के लिए।

पहले UIRefreshControl () बनाओ।

var refreshControl : UIRefreshControl!

आपके दृश्य में DidLoad () विधि जोड़ें:

refreshControl = UIRefreshControl()
    refreshControl.attributedTitle = NSAttributedString(string: "Refreshing..")
    refreshControl.addTarget(self, action: #selector(YourUIViewController.refresh(_:)), forControlEvents: UIControlEvents.ValueChanged)
    self.tableView.addSubview(refreshControl)

और ताज़ा समारोह बनाओ

func refresh(refreshControl: UIRefreshControl) {

    // do something ...

    // reload tableView
    self.tableView.reloadData()

    // End refreshing
    refreshControl.endRefreshing()
}

केलर का पहला सुझाव आईओएस 7 में एक अजीब बग का कारण बनता है जहां व्यू कंट्रोलर फिर से दिखाई देने के बाद तालिका का इन्सेट बढ़ जाता है। Uitableviewcontroller का उपयोग करके दूसरे जवाब में बदलना, मेरे लिए निश्चित चीजें।


आईओएस 10 स्विफ्ट 3.0

यह आसान है

import UIKit

class ViewControllerA: UIViewController, UITableViewDataSource, UITableViewDelegate {

    @IBOutlet weak var myTableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()

        myTableView.delegate = self
        myTableView.dataSource = self

        if #available(iOS 10.0, *) {
            let refreshControl = UIRefreshControl()
            let title = NSLocalizedString("PullToRefresh", comment: "Pull to refresh")
            refreshControl.attributedTitle = NSAttributedString(string: title)
            refreshControl.addTarget(self,
                                     action: #selector(refreshOptions(sender:)),
                                     for: .valueChanged)
            myTableView.refreshControl = refreshControl
        }
    }

    @objc private func refreshOptions(sender: UIRefreshControl) {
        // Perform actions to refresh the content
        // ...
        // and then dismiss the control
        sender.endRefreshing()
    }

    // MARK: - Table view data source

    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 12
    }


    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath)

        cell.textLabel?.text = "Cell \(String(indexPath.row))"
        return cell
    }

}

यदि आप आईओएस 10 यूआईआरफ्रेश कंट्रोल के बारे में जानना चाहते हैं तो here पढ़ें।


खैर UIRefreshControl एक UIView सबक्लास है, इसलिए आप इसे अपने आप उपयोग कर सकते हैं। मुझे यकीन नहीं है कि यह कैसे खुद को प्रस्तुत करता है। प्रतिपादन बस फ्रेम पर निर्भर हो सकता है, लेकिन यह UIScrollView या UITableViewController पर भी भरोसा कर सकता है।

किसी भी तरह से, यह एक सुरुचिपूर्ण समाधान की तुलना में एक हैक के अधिक होने जा रहा है। मैं अनुशंसा करता हूं कि आप उपलब्ध तृतीय पक्ष क्लोन में से किसी एक को देखें या अपना खुद का लिखें।

ODRefreshControl

SlimeRefresh


मैंने सफलतापूर्वक तुरंत अपने ऑडियो प्लेबैक को रोक दिया:

-(void)stopAudio
    {
        @synchronized(audioLock) {
            audioLock=[NSNumber numberWithBool:false];
            OSStatus err;
            err=AudioQueueReset (_audioQueue);
            if (err != noErr)
            {
                NSLog(@"AudioQueueReset() error: %d", (int)err);
            }
            err=AudioQueueStop (_audioQueue, YES);
            if (err != noErr)
            {
                NSLog(@"AudioQueueStop() error: %d", (int)err);
            }
            err=AudioQueueDispose (_audioQueue, YES);
            if (err != noErr)
            {
                NSLog(@"AudioQueueDispose() error: %d", (int)err);
            }
        }
    }

और मेरे में:

void audioCallback(void *custom_data, AudioQueueRef queue, AudioQueueBufferRef buffer)

मैंने केवल अपनी कतार में और सामान डाला है यदि:

myObject *weakSelf = (__bridge myObject *)custom_data;
@synchronized(weakSelf -> audioLock) {
    if ([weakSelf -> audioLock boolValue]) {
         Put_more_stuff_on_queue
    }

मेरे विशेष मामले में मैं प्लेबैक एएसी-एलसी ऑडियो।





objective-c ios uitableview ios6 uirefreshcontrol