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 (Support Library سے) استعمال ہوتا ہے — RecyclerView یا NestedScrollView کے لیے ایک ViewGroup ریپر۔
  • دونوں APIs سننے والوں کے ذریعے رنگوں، اشاروں اور کال بیکس کی حسب ضرورت کو سپورٹ کرتی ہیں (iOS: UIRefreshControl.target-action، Android: setOnRefreshListener)۔
  • جب فہرست اوپری پوزیشن میں نہ ہو تو Pull-to-Refresh خود بخود بلاک ہو جاتا ہے — اسکرول کرنے کے ساتھ تنازعہ آرکیٹیکچرل طور پر خارج کر دیا گیا ہے۔

Pull-to-Refresh کیا ہے؟

Pull-to-Refresh ایک صارف انٹرفیس پیٹرن ہے جہاں صارف مواد کو ریفریش کرنے کے لیے کسی فہرست یا اسکرول کرنے کے قابل علاقے کو نیچے کھینچتا ہے (pull down)۔ بصری طور پر، اشارے کے ساتھ ایک لوڈنگ اشارہ (اسپنر) ہوتا ہے جو اسکرین کے اوپر ظاہر ہوتا ہے اور ڈیٹا موصول ہونے کے بعد غائب ہو جاتا ہے۔ یہ پیٹرن iPhone کے لیے Tweetie ایپ (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 Pull-to-Refresh کے لیے معیاری iOS کنٹرول ہے، جو iOS 6 سے دستیاب ہے۔ UIRefreshControl کو refreshControl پراپرٹی (iOS 10+) کے ذریعے UITableViewController میں یا پرانے ورژن میں ٹیبل کے سب ویو کے طور پر شامل کیا جاتا ہے۔ اس میں حسب ضرورت رنگ (tintColor)، title وصف اور ایک لیبل کے ساتھ منسوب سٹرنگ (مثلاً "اپ ڈیٹ ہو رہا ہے...") کے ساتھ ایک بلٹ ان اسپنر شامل ہے۔

UIRefreshControl target-action میکانزم کے ذریعے کام کرتا ہے: جب اشارہ فعال ہوتا ہے، مخصوص طریقہ کال کیا جاتا ہے (مثلاً refresh(_:))۔ طریقہ کے اندر، غیر متزامن ڈیٹا لوڈنگ کی جاتی ہے۔ مکمل ہونے کے بعد، endRefreshing() کال کیا جاتا ہے، جو اینیمیشن کے ساتھ اشارے کو چھپاتا ہے۔ UIRefreshControl خود بخود اشارے کی حساسیت کا انتظام کرتا ہے — یہ صرف اس وقت فعال ہوتا ہے جب ٹیبل اوپری پوزیشن میں ہو (contentOffset.y <= 0)۔

tintColor پراپرٹی اسپنر کا رنگ سیٹ کرتی ہے۔ attributedTitle مکمل ہونے کے بعد "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+ لائبریری (Compose کے لیے androidx.compose.material3.pulltorefresh) سے نئے Material Pull-to-Refresh کے استعمال کی سفارش کرتا ہے۔ نیا API اسپرنگ اینیمیشن سپورٹ اور وال پیپر کی بنیاد پر انکولی رنگ کے ساتھ ایک متحرک اشارے استعمال کرتا ہے۔ SwipeRefreshLayout Android 12 سے نیچے کے ورژنز کے لیے مطابقت رکھتا ہے۔

بہترین طریقہ کار اور عام غلطیاں

Pull-to-Refresh ایک سادہ پیٹرن ہے جسے نافذ کرنا آسان ہے، لیکن اس میں کئی عام غلطیاں ہیں جو صارف کے تجربے کو کم کرتی ہیں۔ آئیے ان کا جائزہ لیتے ہیں اور انہیں روکنے کے طریقے دیکھتے ہیں۔

  • ڈبل ریفریش — صارف لوڈنگ مکمل ہونے سے پہلے کئی بار فہرست کھینچ سکتا ہے۔ حل: شروع میں 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)

حسب ضرورت اسپنر رنگ اور منسوب عنوان کے ساتھ 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: "ریفریش کرنے کے لیے کھینچیں"
        )
        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 سیٹ کرتی ہے۔ .valueChanged ایونٹ کے ساتھ addTarget اشارہ فعال ہونے پر فائر ہوتا ہے۔ endRefreshing() لازمی ہے — اس کے بغیر اشارہ غیر معینہ مدت تک گھومتا رہے گا۔ غیر متزامن لوڈنگ DispatchQueue.main.asyncAfter کے ساتھ مصنوعی طور پر کی گئی ہے — حقیقی پروجیکٹ میں، URLSession یا async/await استعمال کریں۔

مثال 2: Android میں SwipeRefreshLayout (Kotlin)

حسب ضرورت اشارے کے رنگوں کے ساتھ SwipeRefreshLayout میں RecyclerView لپیٹتا ہے۔ 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 اشارے کے رنگ سیٹ کرتا ہے۔ isRefreshing = false کو finally بلاک میں کال کیا جاتا ہے تاکہ لوڈنگ کی غلطی پر بھی اشارہ چھپ جائے۔ ViewModelScope.launch fragment کی زندگی کے دورانیے میں ایک coroutine چلاتا ہے — fragment تباہ ہونے پر، coroutine خود بخود منسوخ ہو جاتا ہے، میموری لیک کو روکتا ہے۔

مثال 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-کلوزر لیتا ہے جو Pull-to-Refresh پر عمل کرتا ہے۔ SwiftUI خود بخود ریفریش اشارے دکھاتا اور چھپاتا ہے، حالت کی دوڑ کا انتظام کرتا ہے (موجودہ ریفریش مکمل ہونے تک نیا ریفریش شروع نہیں کرتا)، اور اینیمیشن کو پلیٹ فارم کے مطابق ڈھالتا ہے۔ iOS 15+ کے لیے، SwiftUI میں Pull-to-Refresh کو نافذ کرنے کا یہ ترجیحی طریقہ ہے۔

اکثر پوچھے گئے سوالات

کیا SwiftUI میں Pull-to-Refresh کام کرتا ہے؟

ہاں، SwiftUI List یا ScrollView کے لیے .refreshable موڈیفائر فراہم کرتا ہے، جو iOS 15 سے دستیاب ہے۔ کلوزر کے اندر، غیر متزامن ڈیٹا لوڈنگ کوڈ عمل کرتا ہے۔ SwiftUI خود بخود ریفریش اشارے کا انتظام کرتا ہے اور موجودہ لوڈنگ مکمل ہونے till بار بار ٹریگر کو بلاک کرتا ہے — یہ نئے پروجیکٹس کے لیے معیاری تجویز کردہ طریقہ ہے۔

ڈبل ریفریش کو کیسے روکیں؟

isRefreshing فلیگ استعمال کریں: لوڈنگ شروع کرتے وقت true اور مکمل ہونے کے بعد false سیٹ کریں۔ iOS میں، endRefreshing() کال ہونے تک UIRefreshControl خود بخود بار بار کال کو بلاک کرتا ہے۔ Android میں، onRefresh() کے شروع میں SwipeRefreshLayout.isRefreshing چیک کریں: اگر true ہے — return کریں۔ یہ فی اشارہ ایک درخواست کی ضمانت دیتا ہے۔

کیا Pull-to-Refresh فہرست اسکرول کرنے سے تنازعہ کرتا ہے؟

UIRefreshControl اور SwipeRefreshLayout صرف اس وقت متحرک ہوتے ہیں جب فہرست اوپری پوزیشن میں ہو (contentOffset == 0)۔ آرکیٹیکچر تنازعہ کو ختم کرتا ہے: جب تک فہرست 1px بھی اسکرول کی گئی ہے، Pull-to-Refresh اشارہ فعال نہیں ہوتا۔ اگر تنازعہ پیدا ہوتا ہے، تو Android میں nestedScrollingEnabled یا ٹچ کو روکنے والے حسب ضرورت GestureRecognizer کی موجودگی چیک کریں۔

خلاصہ

  • 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 کلوزر کے ساتھ ایک اعلانیہ موڈیفائر، iOS 15 سے دستیاب۔
  • isRefreshing فلیگ ڈبل ریفریش کو روکتا ہے — دونوں پلیٹ فارمز پر لازمی۔
  • Pull-to-Refresh نیویگیشن کے لیے نہیں ہے — صرف Material Design اور Apple HIG کے مطابق مواد ریفریش کے لیے۔

ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے

IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔

پروجیکٹ پر بحث کریں

مزید پڑھیں