Asosiy fikrlar
Pull-to-Refresh — foydalanuvchi kontentni yangilash uchun ro'yxat yoki aylanadigan maydonni pastga tortadigan foydalanuvchi interfeysi namunasidir. Vizual ravishda imo-ishora ekranning yuqori qismida paydo bo'ladigan va ma'lumot olingandan so'ng yo'qoladigan yuklash indikatori (spinner) bilan birga keladi. Ushbu namuna iPhone uchun Tweetie ilovasi (2008) tomonidan ommalashtirilgan va keyinchalik Apple (iOS 6 — UIRefreshControl) va Google (Android Support Library — SwipeRefreshLayout) tomonidan standartlashtirilgan.
Texnik nuqtai nazardan, Pull-to-Refresh panlash (barmoq siljishini kuzatish) va chegaraga yetganda trigger kombinatsiyasidir. Foydalanuvchi ro'yxatni pastga tortadi, qarshilikni (rezistiv overscroll) yengadi va chegaradan o'tgandan so'ng (~80px iOS da, ~64dp Android da) indikator animatsiyasi va asinxron yuklash boshlanadi. Agar foydalanuvchi barmog'ini chegaradan oldin qo'yib yuborsa — ro'yxat yangilanmasdan boshlang'ich holatga qaytadi.
Material Design Guidelines ga ko'ra, Pull-to-Refresh ishlatilmasligi kerak navigatsiya yoki varaqlarni almashtirish uchun — uning yagona maqsadi ma'lumotlarni yangilashdir. IT Sectr da biz Pull-to-Refresh ni yangiliklar lentalari, buyurtma ro'yxatlari va chatlarda qo'llaymiz, bu yerda ma'lumotlarning yangiligi foydalanuvchi tajribasi uchun muhimdir.
UIRefreshControl — iOS 6 dan boshlab mavjud bo'lgan Pull-to-Refresh uchun standart iOS boshqaruv elementidir. UIRefreshControl UITableViewController ga refreshControl xususiyati (iOS 10+) yoki eski versiyalarda jadvalning subview i sifatida qo'shiladi. U sozlanishi mumkin bo'lgan rang (tintColor), title atributi va yorliqli atributlashtirilgan satr (masalan, “Yangilanmoqda...”) bilan o'rnatilgan spinnerni o'z ichiga oladi.
UIRefreshControl target-action mexanizmi orqali ishlaydi: imo-ishora faollashtirilganda ko'rsatilgan metod (masalan, refresh(_:)) chaqiriladi. Metod ichida asinxron ma'lumot yuklash amalga oshiriladi. Tugatgandan so'ng endRefreshing() chaqiriladi, indikatorni animatsiya bilan yashiradi. UIRefreshControl imo-ishora sezgirligini avtomatik boshqaradi — faqat jadvalning yuqori holatida (contentOffset.y <= 0) ishga tushadi.
tintColor xususiyati spinner rangini o'rnatadi. title atributlari tugagandan so'ng “2 daqiqa oldin yangilandi” matnini ko'rsatishga imkon beradi. iOS 10 dan boshlab, UIRefreshControl UIActivityIndicatorView yoki doimiy maxsus ko'rinishlar orqali maxsus animatsiyalarni qo'llab-quvvatlaydi. IT Sectr da biz tintColor ni brendga moslashtiramiz va attributedTitle orqali oxirgi yangilanish vaqtini ko'rsatamiz — bu foydalanuvchilarning ma'lumotlarga ishonchini oshiradi.
SwipeRefreshLayout — Android Support Library dan (androidx.swiperefreshlayout) ViewGroup bo'lib, aylanadigan kontentni (RecyclerView, NestedScrollView, ListView) o'rab oladi va Pull-to-Refresh funksionalligini qo'shadi. UIRefreshControl dan farqli o'laroq (boshqaruv elementi, konteyner emas), SwipeRefreshLayout bolaning teginish hodisalarini tutib oladigan va chegaradan o'tganda yangilanish indikatorini ishga tushiradigan konteynerdir.
SwipeRefreshLayout setColorSchemeColors() orqali rang sozlash bilan Material Design aylana progress indikatoridan foydalanadi. setOnRefreshListener metodi asinxron yuklash amalga oshiriladigan onRefresh() qayta chaqiruvini o'rnatadi. Tugatgandan so'ng indikatorni yashirish uchun setRefreshing(false) chaqiriladi. Muhim: setRefreshing(true) onRefresh() ni qayta chaqiradi — shuning uchun dasturiy yangilashni boshlash uchun flag yoki post metoddan foydalaning.
setProgressBackgroundColorSchemeResource xususiyati indikator fonini o'zgartiradi. setSize(SwipeRefreshLayout.LARGE) — spinner o'lchami. XML layout da SwipeRefreshLayout RecyclerView ni o'rab oladi: swipe_refresh_layout → recycler_view. Google I/O 2024 ga ko'ra, SwipeRefreshLayout kontent lentalari bo'lgan Android ilovalarining 85% ida ishlatiladi. IT Sectr da biz asinxron yuklanadigan ro'yxatlari bo'lgan barcha ekranlarni SwipeRefreshLayout bilan o'raymiz — bu Android ning barcha versiyalarida yagona UX ni ta'minlaydi.
Android 12 (Material You) dan boshlab, Google material-1.6.0+ kutubxonasidan (Compose uchun androidx.compose.material3.pulltorefresh) yangi Material Pull-to-Refresh dan foydalanishni tavsiya qiladi. Yangi API spring animatsiyasi va devor qog'ozi asosida adaptiv rang qo'llab-quvvatlashi bilan animatsiyalangan indikatordan foydalanadi. SwipeRefreshLayout Android 12 dan past versiyalar uchun mos keladi.
Pull-to-Refresh — amalga oshirish oson bo'lgan namuna, ammo UX ni pasaytiradigan bir nechta odatiy xatolarni o'z ichiga oladi. Keling, ularni va oldini olish usullarini ko'rib chiqaylik.
IT Sectr da biz test serverining loglarida takrorlanuvchi so'rovlarni aniqlaganimizdan so'ng har bir loyihada isRefreshing tekshiruvini qo'shdik — ma'lum bo'lishicha, tez barmoqli foydalanuvchilar yangilanishni ketma-ket 3 martagacha ishga tushirgan.
UITableViewController ga maxsus spinner rangi va attributed title bilan Pull-to-Refresh qo'shadi. Ma'lumot yuklangandan so'ng indikator yashiriladi.
import UIKit
class FeedTableViewController: UITableViewController {
private var items: [String] = []
override func viewDidLoad() {
super.viewDidLoad()
tableView.refreshControl = UIRefreshControl()
refreshControl?.tintColor = .systemBlue
refreshControl?.attributedTitle = NSAttributedString(
string: “Yangilash uchun torting”
)
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 xususiyati (iOS 10+) UIRefreshControl ni o'rnatadi. .valueChanged hodisasi bilan addTarget imo-ishora faollashganda ishga tushadi. endRefreshing() majburiy — usiz indikator cheksiz aylanadi. Asinxron yuklash DispatchQueue.main.asyncAfter bilan simulyatsiya qilinadi — haqiqiy loyihada URLSession yoki async/await bo'ladi.
RecyclerView ni maxsus indikator ranglari bilan SwipeRefreshLayout da o'rab oladi. onRefresh yuklashni boshlaydi va tugagandan so'ng indikatorni yashiradi.
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 aylanma indikatorining ranglarini o'rnatadi. isRefreshing = false majburiy ravishda finally da chaqiriladi, shunda yuklash xatosi bo'lganda ham indikator yashiriladi. ViewModelScope.launch fragmentning hayot aylanishida korutinni bajaradi — fragment yo'q qilinganda korutin avtomatik bekor qilinadi, xotira oqishining oldini oladi.
Zamonaviy SwiftUI List yoki ScrollView ga avtomatik Pull-to-Refresh qo'shadigan .refreshable modifikatorini taqdim etadi.
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 modifikatori Pull-to-Refresh vaqtida bajariladigan async-closure ni qabul qiladi. SwiftUI avtomatik ravishda yangilash indikatorini ko'rsatadi va yashiradi, holat poygasini boshqaradi (joriy yuklash tugamaguncha qayta yuklashni boshlamaydi) va animatsiyani platformaga moslashtiradi. iOS 15+ uchun bu SwiftUI da Pull-to-Refresh ni amalga oshirishning preferred usulidir.
Tez-tez beriladigan savollar
Ha, SwiftUI iOS 15 dan boshlab List yoki ScrollView uchun .refreshable modifikatorini taqdim etadi. Closure ichida ma'lumot yuklashning async kodi bajariladi. SwiftUI avtomatik yangilash indikatorini boshqaradi va joriy yuklash tugamaguncha qayta ishga tushirishlarni bloklaydi — bu yangi loyihalar uchun standart recommended yondashuvdir.
isRefreshing flagidan foydalaning: yuklash boshida true va tugagandan so'ng false o'rnating. iOS da UIRefreshControl endRefreshing() chaqirilmaguncha qayta chaqiruvni avtomatik bloklaydi. Android da onRefresh() boshida SwipeRefreshLayout.isRefreshing ni tekshiring: true bo'lsa — return. Bu bir imo-ishora uchun bitta so'rovni kafolatlaydi.
UIRefreshControl va SwipeRefreshLayout faqat ro'yxatning yuqori holatida (contentOffset == 0) ishga tushadi. Arxitektura ziddiyatni istisno qiladi: ro'yxat hatto 1px aylantirilgan bo'lsa ham, Pull-to-Refresh imo-ishorasi faollashmaydi. Agar ziddiyat yuzaga kelsa — Android da nestedScrollingEnabled ni yoki teginishlarni tutib oladigan maxsus GestureRecognizer larni tekshiring.
Xulosa
Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz
IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.