Pull-to-Refresh: मूलबातें, RefreshControl और UIRefreshControl

लेखक: IT Sectr प्रकाशित: 2026-02-27 पढ़ने का समय: 8 मिनट
Pull-to-Refresh एक मोबाइल इंटरफ़ेस पैटर्न है जिसमें यूजर अपनी उंगली से लिस्ट को नीचे खींचता है, जिससे नए डेटा का लोडिंग शुरू होता है। इस इशारे के साथ एक दृश्य संकेतक होता है — घूमता हुआ स्पिनर या एनिमेटेड आइकन — जो लोडिंग पूरा होने पर गायब हो जाता है। Apple HIG के UX विश्लेषण के अनुसार, Pull-to-Refresh Tweetie (2008) में अपनी शुरुआत और Apple और Google द्वारा बाद के मानकीकरण के बाद से समाचार फीड, सोशल नेटवर्क और ईमेल क्लाइंट में सामग्री अपडेट करने का मानक तंत्र बन गया है।

मुख्य बातें

  • Pull-to-Refresh एक दृश्य लोडिंग संकेतक के साथ डेटा अपडेट करने के लिए लिस्ट को नीचे खींचने का इशारा है।
  • iOS में UIRefreshControl (iOS 6+) का उपयोग किया जाता है, जिसे refreshControl प्रॉपर्टी के माध्यम से UITableViewController या UIScrollView में जोड़ा जाता है।
  • Android में SwipeRefreshLayout (सपोर्ट लाइब्रेरी से) का उपयोग किया जाता है — RecyclerView या NestedScrollView के लिए एक ViewGroup रैपर।
  • दोनों API listener के माध्यम से रंगों, संकेतकों और कॉलबैक के अनुकूलन का समर्थन करते हैं (iOS: UIRefreshControl.target-action, Android: setOnRefreshListener)
  • Pull-to-Refresh स्वचालित रूप से ब्लॉक हो जाता है जब लिस्ट शीर्ष स्थिति में नहीं होती — स्क्रोलिंग के साथ टकराव को आर्किटेक्चरल रूप से बाहर रखा जाता है।

Pull-to-Refresh क्या है?

Pull-to-Refresh एक यूजर इंटरफ़ेस पैटर्न है जहां यूजर सामग्री को रिफ्रेश करने के लिए किसी लिस्ट या स्क्रोल करने योग्य क्षेत्र को नीचे खींचता है (पुल डाउन)। दृश्य रूप से, इशारे के साथ एक लोडिंग संकेतक (स्पिनर) होता है जो स्क्रीन के शीर्ष पर दिखाई देता है और डेटा प्राप्त होने के बाद गायब हो जाता है। इस पैटर्न को Tweetie एप द्वारा iPhone (2008) के लिए लोकप्रिय बनाया गया और बाद में Apple (iOS 6 — UIRefreshControl) और Google (Android Support Library — SwipeRefreshLayout) द्वारा मानकीकृत किया गया।

तकनीकी दृष्टिकोण से, Pull-to-Refresh पैनिंग (उंगली के विस्थापन को ट्रैक करना) और एक सीमा तक पहुंचने पर एक ट्रिगर का संयोजन है। यूजर प्रतिरोध (प्रतिरोधी ओवरस्क्रॉल) को पार करते हुए लिस्ट को नीचे खींचता है, और सीमा (~80px iOS पर, ~64dp Android पर) पार करने पर, संकेतक एनिमेशन और असिंक लोडिंग शुरू होता है। यदि यूजर सीमा से पहले अपनी उंगली छोड़ देता है — तो लिस्ट बिना अपडेट किए अपनी मूल स्थिति में लौट जाती है।

Material Design गाइडलाइंस के अनुसार, Pull-to-Refresh का उपयोग नहीं किया जाना चाहिए नेविगेशन या टैब स्विचिंग के लिए — इसका एकमात्र उद्देश्य डेटा रिफ्रेश है। IT Sectr में, हम Pull-to-Refresh का उपयोग समाचार फीड, ऑर्डर फीड और चैट में करते हैं जहां डेटा की ताजगी यूजर अनुभव के लिए महत्वपूर्ण है।

iOS में Pull-to-Refresh: UIRefreshControl

UIRefreshControl iOS में Pull-to-Refresh के लिए एक मानक नियंत्रण है, जो iOS 6 से उपलब्ध है। UIRefreshControl को refreshControl प्रॉपर्टी (iOS 10+) के माध्यम से UITableViewController में या पुराने संस्करणों में टेबल के subview के रूप में जोड़ा जाता है। इसमें एक बिल्ट-इन स्पिनर है जिसमें अनुकूलन योग्य रंग (tintColor), title विशेषता और एक कॅप्शन के साथ एक गुणात्मक स्ट्रिंग (उदाहरण के लिए, “अपडेट हो रहा है...”) शामिल है।

UIRefreshControl टार्गेट-एक्शन तंत्र के माध्यम से काम करता है: जब इशारा सक्रिय होता है, तो एक निर्दिष्ट विधि को बुलाया जाता है (उदाहरण के लिए, refresh(_:)) । विधि के अंदर, असिंक डेटा लोडिंग की जाती है। पूरा होने पर, endRefreshing() को बुलाया जाता है, जो एनिमेशन के साथ संकेतक को छुपाता है। UIRefreshControl स्वचालित रूप से इशारे की संवेदनशीलता का प्रबंधन करता है — यह केवल तब ही सक्रिय होता है जब टेबल शीर्ष स्थिति में हो (contentOffset.y <= 0) ।

tintColor प्रॉपर्टी स्पिनर का रंग निर्धारित करती है। title विशेषताएँ पूरा होने पर “2 मिनट पहले अपडेट किया गया” जैसे टेक्स्ट दिखाने की अनुमति देती हैं। iOS 10 से शुरू करके, UIRefreshControl UIActivityIndicatorView या स्थायी कस्टम व्यू के माध्यम से कस्टम एनिमेशन का समर्थन करता है। IT Sectr में, हम ब्रांड के अनुसार tintColor कॉन्फ़िगर करते हैं और attributedTitle के माध्यम से अंतिम अपडेट समय दिखाते हैं — इससे डेटा में यूजर का विश्वास बढ़ता है।

Android में Pull-to-Refresh: SwipeRefreshLayout

SwipeRefreshLayout Android Support Library (androidx.swiperefreshlayout) से एक ViewGroup है जो स्क्रोल करने योग्य सामग्री (RecyclerView, NestedScrollView, ListView) को लपेटता है और Pull-to-Refresh कार्यक्षमता जोड़ता है। UIRefreshControl (जो एक नियंत्रण है, कंटेनर नहीं) के विपरीत, SwipeRefreshLayout एक कंटेनर है जो चाइल्ड के टच इवेंट को इंटरसेप्ट करता है और सीमा पार होने पर रिफ्रेश संकेतक को ट्रिगर करता है।

SwipeRefreshLayout setColorSchemeColors() के माध्यम से रंग अनुकूलन के साथ एक गोलाकार Material Design प्रगति संकेतक का उपयोग करता है। setOnRefreshListener विधि onRefresh() कॉलबैक स्थापित करती है, जिसमें असिंक लोडिंग की जाती है। पूरा होने पर, संकेतक को छुपाने के लिए setRefreshing(false) को बुलाया जाता है। महत्वपूर्ण: setRefreshing(true) onRefresh() को फिर से बुलाता है — इसलिए प्रोग्रामेटिक रिफ्रेश के लिए, एक फ़्लैग या post विधि का उपयोग करें।

setProgressBackgroundColorSchemeResource प्रॉपर्टी संकेतक की पृष्ठभूमि को बदलती है। setSize(SwipeRefreshLayout.LARGE) — स्पिनर का आकार। XML लेआउट में, SwipeRefreshLayout RecyclerView को लपेटता है: swipe_refresh_layout → recycler_view। Google I/O 2024 के अनुसार, SwipeRefreshLayout का उपयोग सामग्री फीड वाले 85% Android एप में किया जाता है। IT Sectr में, हम असिंक रूप से लोड की गई सूचियों के साथ सभी स्क्रीन को SwipeRefreshLayout में लपेटते हैं — यह सभी Android संस्करणों में एक समान UX प्रदान करता है।

Material Pull-to-Refresh (Android 12+)

Android 12 (Material You) से शुरू करते हुए, Google material-1.6.0+ लाइब्रेरी (कंपोज़ के लिए androidx.compose.material3.pulltorefresh) से नए Material Pull-to-Refresh का उपयोग करने की अनुशंसा करती है। नया API स्प्रिंग एनिमेशन समर्थन और वालपेपर पर आधारित अनुकूलन रंग के साथ एक एनिमेटेड संकेतक का उपयोग करता है। SwipeRefreshLayout Android 12 से नीचे के संस्करणों के लिए संगत बना रहता है।

सबसे अच्छी प्रथाएं और सामान्य गलतियाँ

Pull-to-Refresh लागू करने में एक सरल पैटर्न है, लेकिन इसमें कई सामान्य गलतियाँ हैं जो UX को ख़राब करती हैं। आइए उन्हें और उन्हें रोकने के तरीकों की समीक्षा करें।

  • डबल रिफ्रेश — लोडिंग पूरा होने से पहले यूजर लिस्ट को कई बार खींच सकता है। हल: शुरुआत में isRefreshing फ़्लैग सेट करें और onRefresh() में इसे जाँचें। iOS में, endRefreshing() को केवल पूरा होने के बाद ही बुलाया जाता है; UIRefreshControl में इशारे का ब्लॉकिंग बिल्ट-इन है।
  • फ़ीडबैक की कमी — लोडिंग संकेतक यूजर द्वारा सीमा पार करने के बाद ही सजार होना चाहिए। छूने पर तुरंत संकेतक न दिखाएं — यह भ्रमित करने वाला है। iOS और Android यह स्वचालित रूप से करते हैं।
  • रिफ्रेश समय की अनदेखी — यदि डेटा 200 ms में रिफ्रेश होता है, तो संकेतक कम से कम 500 ms के लिए दिखाया जाना चाहिए ताकि यूजर अपडेट को नोटिस करे। UIRefreshControl में एक न्यूनतम एनिमेशन समय है; Android में, न्यूनतम प्रदर्शन समय के लिए Handler.postDelayed का उपयोग करें।
  • कीबोर्ड के साथ टकराव — खुले कीबोर्ड के साथ, Pull-to-Refresh आकस्मिक रूप से ट्रिगर हो सकता है। iOS में view.endEditing(true) और Android में InputMethodManager.hideSoftInputFromWindow() के माध्यम से इशारा शुरू होने पर कीबोर्ड छुपाएँ।
  • इस्तेमाल रिफ्रेश के लिए नहीं — Pull-to-Refresh का उपयोग नेविगेशन (टैब स्विचिंग, वापस जाना) के लिए न करें। यह दोनों प्लेटफ़ॉर्म के HIG का उल्लंघन करता है और यूजरों को भ्रमित करता है।

IT Sectr में, हमने परीक्षण सर्वर लॉग में डबलिकेट अनुरोधों की खोज के बाद प्रत्येक परियोजना में isRefreshing जाँच जोड़ी — पता चला कि तेज़ उंगलियों वाले यूजर लगातार 3 बार तक रिफ्रेश कर रहे थे।

Swift और Kotlin में कोड उदाहरण

उदाहरण 1: iOS में UIRefreshControl (Swift)

कस्टम स्पिनर रंग और attributed title के साथ UITableViewController में Pull-to-Refresh जोड़ता है। डेटा लोड होने के बाद, संकेतक गायब हो जाता है।

swift
import UIKit

class FeedTableViewController: UITableViewController {

    private var items: [String] = []

    override func viewDidLoad() {
        super.viewDidLoad()

        tableView.refreshControl = UIRefreshControl()
        refreshControl?.tintColor = .systemBlue
        refreshControl?.attributedTitle = NSAttributedString(
            string: "Pull down to refresh"
        )
        refreshControl?.addTarget(
            self,
            action: #selector(refreshData),
            for: .valueChanged
        )
    }

    @objc private func refreshData() {
        DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) {
            self.items = FeedService().fetchLatest()
            self.tableView.reloadData()
            self.refreshControl?.endRefreshing()
        }
    }
}

प्रॉपर्टी tableView.refreshControl (iOS 10+) UIRefreshControl सेट करती है। addTarget इवेंट .valueChanged के साथ इशारा सक्रिय होने पर ट्रिगर होता है। endRefreshing() अनिवार्य है — इसके बिना, संकेतक अनंत रूप से घूमता रहेगा। असिंक लोडिंग को DispatchQueue.main.asyncAfter के साथ अनुकृत किया गया है — एक वास्तविक परियोजना में, URLSession या async/await का उपयोग करें।

उदाहरण 2: Android में SwipeRefreshLayout (Kotlin)

RecyclerView को कस्टम संकेतक रंगों के साथ SwipeRefreshLayout में लपेटता है। onRefresh लोडिंग शुरू करता है और पूरा होने पर संकेतक छुपाता है।

kotlin
class FeedFragment : Fragment() {

    private var _binding: FragmentFeedBinding? = null
    private val binding get() = _binding!!

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        _binding = FragmentFeedBinding.inflate(inflater, container, false)

        binding.swipeRefreshLayout.setColorSchemeColors(
            resources.getColor(R.color.brand_blue, null),
            resources.getColor(R.color.brand_green, null)
        )
        binding.swipeRefreshLayout.setOnRefreshListener {
            loadData()
        }
        return binding.root
    }

    private fun loadData() {
        viewModelScope.launch {
            try {
                val result = repository.getLatestFeed()
                adapter.submitList(result)
            } finally {
                binding.swipeRefreshLayout.isRefreshing = false
            }
        }
    }

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }
}

setColorSchemeColors घूमते Material Design संकेतक के रंग निर्धारित करता है। लोडिंग त्रुटि पर भी संकेतक छुपाने के लिए finally में isRefreshing = false अनिवार्य है। ViewModelScope.launch फ़्रैगमेंट के जीवनचक्र के भीतर एक कोरूटीन निष्पादित करता है — जब फ़्रैगमेंट नष्ट हो जाता है, तो कोरूटीन स्वचालित रूप से रद्द हो जाती है, मेमरी लीक को रोकते हुए।

उदाहरण 3: SwiftUI .refreshable (iOS 15+)

आधुनिक SwiftUI .refreshable मॉडिफायर प्रदान करता है, जो स्वचालित रूप से List या ScrollView में Pull-to-Refresh जोड़ता है।

swift
import SwiftUI

struct FeedView: View {

    @State private var items: [String] = []

    var body: some View {
        List(items, id: \.self) { item in
            Text(item)
        }
        .refreshable {
            items = await FeedService().fetchLatestAsync()
        }
    }
}

.refreshable मॉडिफायर एक async-closure स्वीकार करता है जो Pull-to-Refresh पर निष्पादित होता है। SwiftUI स्वचालित रूप से रिफ्रेश संकेतक को दिखाता और छुपाता है, स्थिति दौड़ का प्रबंधन करता है (वर्तमान लोड पूरा होने तक लोडिंग पुनरारम्भ नहीं करता), और एनिमेशन को प्लेटफ़ॉर्म के अनुसार ढलता है। iOS 15+ के लिए, SwiftUI में Pull-to-Refresh लागू करने का यह पसंदीदा तरीका है।

अक्सर पूछे जाने वाले प्रश्न

क्या Pull-to-Refresh SwiftUI में काम करता है?

हाँ, SwiftUI List या ScrollView के लिए .refreshable मॉडिफायर प्रदान करता है, जो iOS 15 से उपलब्ध है। closure के अंदर, असिंक डेटा लोडिंग कोड निष्पादित होता है। SwiftUI स्वचालित रूप से रिफ्रेश संकेतक का प्रबंधन करता है और वर्तमान लोड पूरा होने तक बार-बार लॉन्च को ब्लॉक करता है — नए प्रोजेक्ट के लिए यह मानक अनुशंसित दृष्टिकोण है।

डबल रिफ्रेश को कैसे रोकें?

isRefreshing फ़्लैग का उपयोग करें: लोडिंग शुरू होने पर इसे true और पूरा होने पर false सेट करें। iOS में, UIRefreshControl endRefreshing() के बुलाए जाने तक बार-बार की कॉल को स्वचालित रूप से ब्लॉक करता है। Android में, onRefresh() की शुरुआत में SwipeRefreshLayout.isRefreshing की जाँच करें: यदि true है — return करें। यह प्रति इशारे एक अनुरोध की गारंटी देता है।

क्या Pull-to-Refresh लिस्ट स्क्रोलिंग के साथ टकराता है?

UIRefreshControl और SwipeRefreshLayout केवल तब ही ट्रिगर होते हैं जब लिस्ट शीर्ष स्थिति में हो (contentOffset == 0)। आर्किटेक्चर टकराव को समाप्त करती है: जब तक लिस्ट 1पिक्सल भी स्क्रोल की जाती है, Pull-to-Refresh इशारा सक्रिय नहीं होता है। यदि टकराव होता है — Android में nestedScrollingEnabled या टच को इंटरसेप्ट करने वाले कस्टम GestureRecognizers की जाँच करें।

सारांश

  • Pull-to-Refresh एक डेटा रिफ्रेश पैटर्न है जो लिस्ट को नीचे खींचकर किया जाता है, सभी मोबाइल प्लेटफ़ॉर्म पर Apple और Google द्वारा मानकीकृत।
  • iOS में UIRefreshControl — target-action, tintColor, attributedTitle और अनिवार्य endRefreshing() के साथ एक नियंत्रण।
  • Android में SwipeRefreshLayout — setOnRefreshListener, setColorSchemeColors और isRefreshing के साथ एक ViewGroup कंटेनर।
  • Material Pull-to-Refresh (Android 12+) — स्प्रिंग एनिमेशन के साथ एक नया API, नए प्रोजेक्ट के लिए अनुशंसित।
  • SwiftUI .refreshable — async closure के साथ एक घोषणात्मक मॉडिफायर, iOS 15 से उपलब्ध।
  • isRefreshing फ़्लैग डबल रिफ्रेश को रोकता है — दोनों प्लेटफ़ॉर्म पर अनिवार्य।
  • Pull-to-Refresh नेविगेशन के लिए अभिप्रेत नहीं है — केवल Material Design और Apple HIG के अनुसार सामग्री रिफ्रेश के लिए।

हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे

IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।

परियोजना पर चर्चा करें

यह भी पढ़ें