iOS ์•ฑ ๊ฐœ๋ฐœ ์ข…ํ•ฉ๋ฐ˜/TIL

7์ฃผ์ฐจ_2์ผ์ฐจ_์•ฑ ๊ฐœ๋ฐœ ์ˆ™๋ จ_ScrollView & Pull to Refresh_TIL

yeggrrr๐Ÿผ 2024. 4. 16. 20:26


<TIL>

์–ด์ œ๋Š” ์œ„์‹œ ๋ฆฌ์ŠคํŠธ ๋งŒ๋“ค๊ธฐ ๊ฐœ์ธ๊ณผ์ œ ํ•„์ˆ˜ ๊ตฌํ˜„๊นŒ์ง€ ๋งŒ๋“ค์–ด๋ณด๊ณ ,
์˜ค๋Š˜์€ ์ถ”๊ฐ€ ๊ตฌํ˜„ ์‹œ๋„ํ•ด๋ดค๋‹ค.

์ถ”๊ฐ€๊ตฌํ˜„์œผ๋กœ ์œ„์‹œ ๋ฆฌ์ŠคํŠธ ์‚ญ์ œ, ๋‹น๊ฒจ์„œ ์ƒˆ๋กœ๊ณ ์นจ ๊ตฌํ˜„์ด ์žˆ์—ˆ๋‹ค.
์ถ”๊ฐ€์ ์œผ๋กœ ์œ„์‹œ๋ฆฌ์ŠคํŠธ์— ๋‹ด๊ธฐ ๋ฒ„ํŠผ์„ ํด๋ฆญํ–ˆ์„ ๋•Œ, alert๊ฐ€ ๋œฐ ์ˆ˜ ์žˆ๋„๋ก ์ถ”๊ฐ€ํ–ˆ๋‹ค.
๊ทธ๋ฆฌ๊ณ  ์œ„์‹œ๋ฆฌ์ŠคํŠธ์—์„œ ํ•ด๋‹น ์ƒํ’ˆ์„ ์‚ญ์ œ๋ฅผ ํ•œ ํ›„,
์•ฑ์„ ์ข…๋ฃŒํ–ˆ๋‹ค๊ฐ€ ๋‹ค์‹œ ํ‚ค๋ฉด ๊ทธ๋Œ€๋กœ ๋‹ค์‹œ ๋˜๋Œ์•„๊ฐ€์žˆ๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ๋‹ค.
(๋‚ด๊ฐ€ ๋ฐ”๋ณด์˜€์Œ.. ๐Ÿ˜…์ฝ”์–ด๋ฐ์ดํ„ฐ๋กœ ๋ฐ์ดํ„ฐ ์ €์žฅํ•ด๋†“๊ณ , ์ฝ”์–ด๋ฐ์ดํ„ฐ์—์„œ ์‚ญ์ œ๋Š” ์•ˆํ•ด์„œ ์ƒ๊ธด ๋ฌธ์ œ)
๊ทธ๋ž˜์„œ ๋ฐ์ดํ„ฐ์—์„œ ์‚ญ์ œํ•˜๋Š” delete function์„ ๋งŒ๋“  ํ›„,
์…€์ด ์‚ญ์ œ๋œ ์ดํ›„์— ์‹คํ–‰๋˜๋„๋ก ๋ณ€๊ฒฝํ•ด์ฃผ์—ˆ๋‹ค.

์˜ค๋Š˜ Lv4 '์œ„์‹œ๋ฆฌ์ŠคํŠธ ์‚ญ์ œ'๋Š” ์™„๋ฃŒ!
์ด์–ด์„œ Lv5 '๋‹น๊ฒจ์„œ ์ƒˆ๋กœ๊ณ ์นจ'์„ ๊ตฌํ˜„ํ•˜๋‹ค๊ฐ€
scrollView์—์„œ ์˜คํ† ๋ ˆ์ด์•„์›ƒ ์žก๋Š”๋ฐ ์–ด๋ ค์›€์ด ์žˆ์–ด์„œ

commit ํ•ด๋…ผ ํŒŒ์ผ๋กœ ๋‹ค์‹œ ๋˜๋Œ๋ ค๋†“๊ณ , ์œ ํŠœ๋ธŒ๋กœ scrollView ๊ด€๋ จํ•ด์„œ ๊ณต๋ถ€ํ–ˆ๋‹ค.

ํ•ด๋ณด๊ณ  ์•ˆ๋˜๋ฉด ์ผ๋‹จ์€ tableView๋กœ ์ƒˆ๋กœ๊ณ ์นจ ๊ตฌํ˜„์„ ํ•ด๋ณด๋ ค๊ณ  ํ•œ๋‹ค!

๊ณผ์ œ ๊ตฌํ˜„ ๊ณผ์ •์— ๊ด€๋ จํ•ด์„œ๋Š” ๋‚ด์ผ ์ •๋ฆฌํ•  ์ƒ๊ฐ์ด๋‹ค.
์˜ค๋Š˜์€ ๊ฐ„๋žตํ•˜๊ฒŒ ์ด๋ฒˆ ๊ณผ์ œ์— ๋Œ€ํ•ด์„œ ์ •๋ฆฌํ•˜๊ณ ,
scrollView์— ๋Œ€ํ•ด์„œ ๊ณต๋ถ€ํ•œ ๋‚ด์šฉ๊ณผ ๊ณผ์ œ์— ์ถ”๊ฐ€ํ•œ ๊ณผ์ •์„ ์ •๋ฆฌํ•ด๋ณด๋ ค๊ณ  ํ•œ๋‹ค.



์œ„์‹œ ๋ฆฌ์ŠคํŠธ ๋งŒ๋“ค๊ธฐ


0
Lv1~4 ๊ตฌํ˜„ ํ˜„ํ™ฉ


scrollView

 

๋ฉ”์ธํ™”๋ฉด์„ ์•„๋ž˜๋กœ ์Šคํฌ๋กคํ•˜๋ฉด,
์ƒˆ๋กœ๊ณ ์นจ์ด ๋˜์„œ '๋‹ค๋ฅธ ์ƒํ’ˆ ๋ณด๊ธฐ ๋ฒ„ํŠผ'์„ ํด๋ฆญํ–ˆ์„ ๋•Œ์™€ ๊ฐ™์€ ๋™์ž‘์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์•ผํ•œ๋‹ค.

 ๋…ธ๋ž€์ƒ‰์œผ๋กœ ํ‘œ์‹œํ•œ ๋ถ€๋ถ„!
imageView์™€ StackView๋กœ ๋ฌถ์—ˆ๋˜ Label 3๊ฐœ
์• ๋„ค๋“ค๋งŒ ์Šคํฌ๋กค ๋˜๋กœ๋ก ํ•˜๋ ค๊ณ  ํ•œ๋‹ค.

์˜ค๋Š˜ ์‹œ๋„ํ–ˆ๋‹ค๊ฐ€ ์‹คํŒจํ–ˆ๋˜ ์ด์œ ๊ฐ€
ScrollView ์ถ”๊ฐ€ํ•˜๊ณ , ์•ˆ์— UIView ์ถ”๊ฐ€ํ•˜๊ณ 
๊ทธ ์•ˆ์— ์ด ๋‘ ๊ฐ€์ง€ ๋…€์„๋“ค์„ ๋„ฃ์–ด์คฌ์—ˆ๋Š”๋ฐ,

์˜คํ† ๋ ˆ์ด์•„์›ƒ์ด ๋„ˆ๋ฌด ๋งŽ์•„์ ธ์„œ ์–ด๋Š ๋ถ€๋ถ„์„ ๋†“์นœ๊ฑด์ง€ ์•Œ ์ˆ˜ ์—†์–ด์„œ
์ด๊ฒƒ์ €๊ฒƒ ๋ฐ”๊ฟ”๋ณด๋‹ค๊ฐ€ ๋’ค์ฃฝ๋ฐ•์ฃฝ ๋˜์–ด๋ฒ„๋ ธ์—ˆ๋‹ค..

๊ทธ๋ž˜์„œ ๋‹ค์‹œ ์ฐจ๊ทผ์ฐจ๊ทผ ScrollView ๋ธ”๋กœ๊ทธ๋ฅผ ๋ณด๊ณ  ํ•ด๋ณด๊ธฐ!!
(์ฐธ๊ณ ํ–ˆ๋˜ ๋ธ”๋กœ๊ทธ : https://nareunhagae.tistory.com/45
)

 

[ScrollView] Auto Layout ์„ค์ •์ด ์–ด๋ ต๋‹ค๋ฉด ์ด๊ฑธ ๋ณด์„ธ์š”! - iOS

์ž˜ ์ง€๋‚ด์…จ๋‚˜์š”..? (๋Œ€์ถฉ ์™œ ์š”์ฆ˜์— ํฌ์ŠคํŒ… ์•ˆํ–ˆ๋ƒ๋Š” ๋ถ„๋“ค์˜ ๋ˆˆ๋น›์„ ๋ฐ›๋Š” ๋‚˜) (๋ญ”๊ฐ€ ๊ธฐ๋Œ€์— ๋ถ€์‘์„ ํ•ด์•ผํ•  ๊ฒƒ ๊ฐ™์€ ๋‚˜) . . . . . . ๊ทธ๋ž˜์„œ ์ฃผ์ œ๋ฅผ ํ•˜๋‚˜ ๋ฌผ๊ณ ์™”์Šต๋‹ˆ๋‹ค~~~! (ํ•˜ํ•˜..) ์˜ค๋Š˜์€ ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„

nareunhagae.tistory.com

์Šคํฌ๋กค ๋ทฐ ์–ด๋ ค์šฐ์‹  ๋ถ„๋“ค ์ด๊ฑฐ ๋ณด์„ธ์š”..
์ง„์งœ ์ •๋ฆฌ ์ž˜๋˜์–ด์žˆ๊ณ , ์ด๊ฑฐ๋ณด๊ณ  ๋”ฐ๋ผํ•ด์„œ ์˜คํ† ๋ ˆ์ด์•„์›ƒ ๊ฒฝ๊ณ ๋ž‘ ์—๋Ÿฌ
๋‹ค ์‚ฌ๋ผ์กŒ์Šต๋‹ˆ๋‹ค!!


์ฒ˜์Œ๋ถ€ํ„ฐ ์Šคํฌ๋กค ๋ทฐ๋ฅผ ์‚ฌ์šฉํ•  ๊ฑธ ์•Œ๊ณ , ๋งŒ๋“ค์–ด์„œ ์‹œ์ž‘ํ–ˆ๋‹ค๋ฉด ์ •๋ง ์ข‹์•˜๊ฒ ์ง€๋งŒ..

LV5 ์ถ”๊ฐ€ ๊ตฌํ˜„์— ์žˆ์—ˆ๊ธฐ ๋•Œ๋ฌธ์—
์ง€๊ธˆ ๋งŒ๋“ค์–ด ๋†“์€ ๋ถ€๋ถ„์„ ์ˆ˜์ •ํ•ด์•ผํ–ˆ๋‹ค!


<ScrollView ์ถ”๊ฐ€ ๊ณผ์ •>

โ‘  UIView๋ฅผ safeArea์— ์ถ”๊ฐ€ํ•˜๊ธฐ

โ‘ก ์ด View ์•ˆ์— ๋„ฃ์œผ๋ ค๋Š” ์š”์†Œ๋“ค ๋„ฃ๊ธฐ
(imageView, StackView(Label 3๊ฐœ))

โ‘ข ScrollView๋ฅผ safeArea์— ์ถ”๊ฐ€ํ•˜๊ธฐ

โ‘ฃ ScrollView์— ์š”์†Œ๋“ค ๋„ฃ์€ View ๋„ฃ๊ธฐ

โ‘ค View๋ฅผ ScrollView์— constraints๋ฅผ leading, trailing, top, bottom ๋ชจ๋‘ 0์œผ๋กœ ๋งž์ถ”๊ธฐ

โ‘ฅ View ๊ธฐ์ค€์œผ๋กœ imageView, StackView(Label 3๊ฐœ) ์˜คํ† ๋ ˆ์ด์•„์›ƒ ์žก๊ธฐ

โ‘ฆ ์ด View๋ฅผ Frame Layout Guide์— Equal Width ํ•ด์ฃผ๊ธฐ
(์œ„ ์•„๋ž˜๋กœ ์Šคํฌ๋กค ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด, Equal Width
์ขŒ์šฐ๋กœ ์Šคํฌ๋กค ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด, Equal Height
์ƒํ•˜์ขŒ์šฐ ์ž์œ ๋ถ„๋ฐฉํ•˜๊ฒŒ ์Šคํฌ๋กค ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด, ์ƒ๋žต)

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ScrollView ์ถ”๊ฐ€ํ•ด์„œ ์˜คํ† ๋ ˆ์ด์•„์›ƒ์žก๊ธฐ ๋!!!


์ด์ œ ์ด ScrollView๋ฅผ ์ฝ”๋“œ์— ์•„์šธ๋ › ์—ฐ๊ฒฐํ•ด์ฃผ๊ณ ,
์ƒˆ๋กœ๊ณ ์นจ ์ฝ”๋“œ ์ž‘์„ฑ๋งŒ ํ•˜๋ฉด ๋œ๋‹ค!

func configureRefreshControl() {
        containerScrollView.refreshControl = UIRefreshControl()
        containerScrollView.refreshControl?.addTarget(self, action: #selector(handleRefreshControl), for: .valueChanged)
    }
 @objc func handleRefreshControl() {
        updateProduct()
        DispatchQueue.main.async {
            self.containerScrollView.refreshControl?.endRefreshing()
        }
}

 

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด, ์ƒˆ๋กœ๊ณ ์นจ์ด ํ™œ์„ฑํ™” ๋œ๋‹ค!
(updateProduct()๋Š” '๋‹ค๋ฅธ ์ƒํ’ˆ ๋ณด๊ธฐ ๋ฒ„ํŠผ' ํด๋ฆญํ–ˆ์„ ๋•Œ, ๋™์ž‘ํ•˜๋Š” ์ฝ”๋“œ์ž„)


๊ทธ๋Ÿฐ๋ฐ, viewDidLoad์— configureRefreshControl()๋ฅผ ์ถ”๊ฐ€ํ•œ ํ›„ ์‹คํ–‰ํ•ด๋ณด๋ฉด?
๋ญ”๊ฐ€ ํ—ˆ์ „ํ•œ ๋Š๋‚Œ์ด ๋“ค ๊ฒƒ์ด๋‹ค.๐Ÿ˜ณ

๊ทธ ์ด์œ ๋Š”! ๋ฆฌํ”„๋ ˆ์‹œ ์ธ๋””์ผ€์ดํ„ฐ๊ฐ€ ๊ณ ์ •๋˜์ง€ ์•Š๊ณ , ๋ฐ”๋กœ ์˜ฌ๋ผ๊ฐ€๊ธฐ ๋•Œ๋ฌธ์—!
์šฐ๋ฆฌ๊ฐ€ ์ž์ฃผ ์‚ฌ์šฉํ•˜๋˜ ์–ดํ”Œ๋“ค์˜ ์ƒˆ๋กœ๊ณ ์นจ๊ณผ ์‚ด์ง ์ด์งˆ๊ฐ์ด ๋“ค์—ˆ๋˜ ๊ฒƒ!!

    @objc func handleRefreshControl() {
        updateProduct()
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
            self.containerScrollView.refreshControl?.endRefreshing()
        }
    }

๋ฐฉ๊ธˆ ์œ„์˜ ์ฝ”๋“œ์—์„œ async์„ asyncAfter๋กœ๋งŒ ๋ฐ”๊ฟ”์ฃผ๋ฉด ๋œ๋‹ค.
๋‹ค์‹œ ์‹คํ–‰ํ•ด๋ณด๋ฉด??

0

์ด๋ ‡๊ฒŒ  0.5์ดˆ๋™์•ˆ ์ž ์‹œ ์ƒˆ๋กœ๊ณ ์นจ์— ๋จธ๋ฌผ๋Ÿฌ์žˆ๋‹ค๊ฐ€
endRefreshing() ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ด์„œ ์ƒˆ๋กœ๊ณ ์นจ์ด ์™„๋ฃŒ๋˜๋Š” ๋ชจ์Šต!






728x90