اہم نکات
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 استعمال کرتے ہیں جہاں ڈیٹا کی تازگی صارف کے تجربے کے لیے اہم ہوتی ہے۔
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 کے ذریعے آخری اپ ڈیٹ کا وقت دکھاتے ہیں — اس سے صارفین کا ڈیٹا پر اعتماد بڑھتا ہے۔
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 فراہم کرتا ہے۔
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 ایک سادہ پیٹرن ہے جسے نافذ کرنا آسان ہے، لیکن اس میں کئی عام غلطیاں ہیں جو صارف کے تجربے کو کم کرتی ہیں۔ آئیے ان کا جائزہ لیتے ہیں اور انہیں روکنے کے طریقے دیکھتے ہیں۔
IT Sectr میں، ہم نے ٹیسٹ سرور لاگز میں ڈپلیکیٹ درخواستیں دریافت کرنے کے بعد ہر پروجیکٹ میں isRefreshing چیک شامل کیا — پتہ چلا کہ تیز انگلیوں والے صارفین لگاتار 3 بار تک ریفریش متحرک کر رہے تھے۔
حسب ضرورت اسپنر رنگ اور منسوب عنوان کے ساتھ UITableViewController میں Pull-to-Refresh شامل کرتا ہے۔ ڈیٹا لوڈ ہونے کے بعد، اشارہ چھپ جاتا ہے۔
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 استعمال کریں۔
حسب ضرورت اشارے کے رنگوں کے ساتھ SwipeRefreshLayout میں RecyclerView لپیٹتا ہے۔ onRefresh لوڈنگ شروع کرتا ہے اور مکمل ہونے کے بعد اشارہ چھپاتا ہے۔
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 خود بخود منسوخ ہو جاتا ہے، میموری لیک کو روکتا ہے۔
جدید SwiftUI .refreshable موڈیفائر فراہم کرتا ہے جو خود بخود List یا ScrollView میں Pull-to-Refresh شامل کرتا ہے۔
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 List یا ScrollView کے لیے .refreshable موڈیفائر فراہم کرتا ہے، جو iOS 15 سے دستیاب ہے۔ کلوزر کے اندر، غیر متزامن ڈیٹا لوڈنگ کوڈ عمل کرتا ہے۔ SwiftUI خود بخود ریفریش اشارے کا انتظام کرتا ہے اور موجودہ لوڈنگ مکمل ہونے till بار بار ٹریگر کو بلاک کرتا ہے — یہ نئے پروجیکٹس کے لیے معیاری تجویز کردہ طریقہ ہے۔
isRefreshing فلیگ استعمال کریں: لوڈنگ شروع کرتے وقت true اور مکمل ہونے کے بعد false سیٹ کریں۔ iOS میں، endRefreshing() کال ہونے تک UIRefreshControl خود بخود بار بار کال کو بلاک کرتا ہے۔ Android میں، onRefresh() کے شروع میں SwipeRefreshLayout.isRefreshing چیک کریں: اگر true ہے — return کریں۔ یہ فی اشارہ ایک درخواست کی ضمانت دیتا ہے۔
UIRefreshControl اور SwipeRefreshLayout صرف اس وقت متحرک ہوتے ہیں جب فہرست اوپری پوزیشن میں ہو (contentOffset == 0)۔ آرکیٹیکچر تنازعہ کو ختم کرتا ہے: جب تک فہرست 1px بھی اسکرول کی گئی ہے، Pull-to-Refresh اشارہ فعال نہیں ہوتا۔ اگر تنازعہ پیدا ہوتا ہے، تو Android میں nestedScrollingEnabled یا ٹچ کو روکنے والے حسب ضرورت GestureRecognizer کی موجودگی چیک کریں۔
خلاصہ
ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے
IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔
مزید پڑھیں