- Published on
๐ WWDC23 - What's new in UIKit
- Authors
- Name
- ์ด์ฐฝ์ค
WWDC23 - Whatโs new in UIKit
๋๋์ด WWDC23์ ๋ง์ด ์ด๋ ธ์ต๋๋ค!
๋ค๋ค VisionOS ์ Vision Pro ๋ณด์ จ๋์??
๋๋ฌด๋๋ฌด ๋๋ผ์์ ๋น์ฅ์ด๋ผ๋ ๊ณต๋ถํ๊ณ ์ถ์ ๋ง์์ด ์ปธ์ง๋ง..
์ค์ ์ ARKit์ ๋ชจ๋ฅธ๋ค๋ฉด ์ฝ๊ฒ ์ ๊ทผํ ์ ์์ ๊ฒ ๊ฐ๋๊ตฐ์..! ๐ญ
๊ทธ๋์ ์ฌ์ ๊ฐ ์ข ์๊ธด๋ค๋ฉด ์ฒ์ฒํ ํ๋์ฉ ๊ณต๋ถํด๋ณด๋ ค๊ณ ํฉ๋๋ค!
์ผ๋จ์ ํ๋ UIKit์ ์ง์คํด์ผ์ฃ !
๊ทธ๋์ ์ฌํด ๋ฅ๋ฅ๋์จ ๊ณต๋ถ์ ์์์ โWhatโs new in UIKitโ ์ผ๋ก ์์ํด๋ณด๋ ค ํฉ๋๋ค.
Architectural Enhancements
์ฐ์ Architectural Enhancements ์ ๋๋ค! (์ด๊ฑฐ ํ๊ตญ์ด๋ก ๋ญ๋ผ๊ณ ๋ฒ์ญํด์ผํ๋์..)
์ด 5๊ฐ์ง์ ํํธ๋ก ๋๋์ด ์ค๋ช ๋๊ณ ์์ต๋๋ค.
Xcode Previews
๋๋์ด Preview๋ฅผ UIKit ์์ ์ผ๋ก ์ฌ์ฉํ ์ ์๊ฒ ๋์์ต๋๋ค! ๐๐
์๋๋ UIKit์์ ์ฑ์ ํ๋ฆฌ๋ทฐ๋ฅผ ์ฑ ๋น๋ ์์ด ๋ณด๋ ค๋ฉด SwiftUI์ feature๋ฅผ ๋น๋ ค์์ ์ฌ์ฉํด์ผ ํ์ฃ .. ๐ญ
์ด์ ๋ import SwiftUI
์์ด ์์ UIKit์์๋ ๊ฐ๋ฅํฉ๋๋ค!
๋ฐ๋ก ์๋กญ๊ฒ ๋ฑ์ฅํ Swift์ macro ๊ธฐ๋ฅ์ ์ฌ์ฉํ๋๋ฐ์..!
์ค์คโฆ #Preview
๊น์ง๋ง ์
๋ ฅ์ ํ๋๋ฐ๋ ์์ Preview ํ๋ฉด์ด ๋ฐ๋ก ๋จ๋ค์โฆ ๐ฎ
#Preview("Home") {
let vc = HomeViewController()
vc.isBold = false
return vc
}
์ด๋ ๊ฒ ์๋ก์ด macro๋ฅผ ์ฌ์ฉํด์ SwiftUI์ ๊ฐ์ด Preview๋ฅผ ์ฌ์ฉํ ์ ์๊ฒ ๋์์ต๋๋ค.
vc.type = .edit
๊ณผ ๊ฐ์ด vc์ ํ๋กํผํฐ๋ ๋ฉ์๋๋ฅผ ๋ฐ๊ฟ๊ฐ๋ฉด์ ์์
ํ ์๋ ์์ด์!
์ด๋ ๊ฒ์..!
๊ทผ๋ฐ์.. ๋ฌธ์ ๊ฐ ํ๋ ์์ต๋๋ค.
iOS 17๋ถํฐ๊ฑฐ๋ ์! ๐ฅฒ ๐ฅฒ ๐ฅฒ
์๋ฌด๋๋ ์ค์ ๋ก ์ฌ์ฉํ๊ธฐ์ ์๊ฐ์ด ์กฐ๊ธ ๊ฑธ๋ฆด ๊ฒ ๊ฐ์ฃ ..?
์ ๋ ์ผ๋จ์ Debug ํ๊ฒ์ 17.0์ผ๋ก ์ค์ ํ๋๊น ๋น๋๋ ๋๋๋ผ๊ตฌ์..
๋์ค์ Releaseํ ๋๋ ๋ณ๋์ ์์ ์ ํด์ฃผ์ด์ผ๊ฒ ์ง๋ง ์ฐ์ ์ ์ด๋ ๊ฒ ์งํํด๋ณด๊ฒ ์ต๋๋ค.
#Preview
๊ฐ ์ ๋ง ํธ๋ฆฌํ ์ ์ ViewController
๋ฟ๋ง ์๋๋ผ UIView
์์๋ ์ฌ์ฉํ ์ ์๋ค๋ ์ ์
๋๋ค.
์ด๋ ๊ฒ ๋ค์ํ ํฌ๊ธฐ์ ์ปดํฌ๋ํธ๋ก ์๊ฐํํด์ฃผ์ด์ ํน์ ๋ชจ๋ฅผ ๋ฒ๊ทธ๋ฅผ ๋ฐฉ์งํ๋๋ฐ๋ ํฐ ๋์์ด ๋ ๊ฒ ๊ฐ๋ค์.
ViewController Life Cycle
๋ค์์ผ๋ก๋ ViewController
์ Life Cycle์ ๋ณ๊ฒฝ์ ์ด ์์ต๋๋ค.
์๋ก์ด ์ฝ๋ฐฑ ํจ์๊ฐ ์ถ๊ฐ๋์๋๋ฐ์.. viewIsAppearing
์ด๋ผ๋ ์ด๋ฆ์ ๊ฐ์ง๊ณ ์์ต๋๋ค.
์ด viewIsAppearing
์ viewWillAppear
์ viewDidAppear
์ฌ์ด์ ํธ์ถ๋๋ค๊ณ ํ๋๋ฐ์..!
๊ทธ๋ฅ viewWillAppear
๋ฅผ ์ฌ์ฉํ๋ฉด ๋๋๊ฑฐ ์๋๋! ํ์ง๋ง..
viewIsAppearing
์ด ํธ์ถ๋๋ ์์ ์ UI์ trait collection์ด ๊ตฌ์ฑ ๋์๊ณ , ๊ฐ ์ปดํฌ๋ํธ๋ค์ด UI ๊ณ์ธต(hierarchy)์ ์ถ๊ฐ๋๊ณ ํ์ ๋ ์์ ์ด๋ผ๊ณ ํฉ๋๋ค.
override func viewDidLoad() {
super.viewDidLoad()
self.view.addSubview(self.label)
self.label.snp.makeConstraints { make in
make.center.equalToSuperview()
}
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
print("View will Appear: \(self.label.frame)")
}
override func viewIsAppearing(_ animated: Bool) {
super.viewIsAppearing(animated)
print("View is Appearing: \(self.label.frame)")
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
print("View did Appear: \(self.label.frame)")
}
์ ๊ทธ๋ผ ์ด๋ ๊ฒ ํด๋๋ฉด ์ด๋ป๊ฒ ์ถ๋ ฅ๋๋ ํ ๋ฒ ๋ณผ๊น์?
๐ค ๐ค ๐ค ๋ ์ด์์์ด ์์กํ์๋๋ฐ์..?
๋ญฅ๋ฏธ..
๋ผ๊ณ ์ฝ์ง์ ํ๋ ์ค ๋ค์ ํ๋ฉด์์ ํด๋ต์ ์ฐพ์ ์ ์์์ต๋๋ค.
viewIsAppearing
์ LayoutSubviews
๋ค ๋ณด๋ค๋ ์์ ์ฝ๋ฐฑ๋๊ฑฐ๋ ์! ๐ซฃ
viewIsAppearing
์ด ๋ฑ์ฅํ ๋ฐฐ๊ฒฝ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
viewWillAppear
๋ ์ปดํฌ๋ํธ๋ค์ด ๊ณ์ธต์ ์ถ๊ฐ๋๊ธฐ ์ด์ ์ ์ฝ๋ฐฑ๋๊ธฐ ๋๋ฌธ์trait collection
์ ์ฌ์ฉํ๊ฑฐ๋view
์ ์ฌ์ด์ฆ์ ์์น์ ๋ฐ๋ฅธ ๋ก์ง์ ์ถ๊ฐํ๊ธฐ์๋ ๋๋ฌด ์ด๋ฆ ๋๋ค.viewDidAppear
๋ ๋ชจ๋ ์ ๋๋ฉ์ด์ ์ด ๋๋ ํ์ ์ฝ๋ฐฑ๋๊ธฐ ๋๋ฌธ์ ์ ๋ฐ์ดํธํ ์์๋ค์ด ๋๋ฌด ๋ฆ๊ฒ ์ ๋ฐ์ดํธ ๋๊ณ , ์ ์ ๋ค์ ์ด๋ฅผ ์ง์ ๋ณด๊ฒ ๋๋ค.layoutSubviews
๋ค๊ณผ ๊ฐ์ ์๊ธฐ์ ์ฝ๋ฐฑ๋๋ ํจ์๊ฐ ํ์ํ๋คโฆ!
๊ทธ๋ฌ๋ฉด ๊ทธ๋ฅ layoutSubviews
์์ ์์
ํ๋ฉด ๋๋๊ฑฐ ์๋๊ฐ์? ๋ผ๋ ์ง๋ฌธ์ด ์๊ธฐ๋ ์ฐฐ๋ ๋ฐ๋ก ๋ ์ค๋ช
ํด์ฃผ์ญ๋๋ค.
layoutSubviews
๋ค์ transition์ด ์์ ๋, ํน์ view
๊ฐ visibleํ ๋์ ๋ช ๋ฒ์ด๊ณ ํธ์ถ ๋ ์ ์์ง๋ง, viewIsAppearing
์ transition๋น ๋ฑ ํ ๋ฒ ๋ง ํธ์ถ๋ฉ๋๋ค.
๋ํ ๋ ์ด์์์ ์ก๋ ๋์์ด ํ์๊ฐ ์์ ๋๋ ํธ์ถ๋๊ธฐ ๋๋ฌธ์ ์ ์ฉํ ์ํฉ๋ ์๊ฒ ์ฃ !
Trait System Enhancements
์ ๋ด์ฉ๊ณผ ์ด์ด์ง๋ ๋ด์ฉ์ธ ๊ฒ ๊ฐ๋ค์!
์ด๊ฑด ๊ทผ๋ฐ ์์ง ์ ๊ฐ ํ์ตํ์ง ๋ชปํ ๋ด์ฉ์ด๋ผโฆ
์ด๋ฐ ๋ด์ฉ์ด ์๋ค๋ ๊ฒ๋ง ์์๋๊ณ ๋์ด๊ฐ๊ฒ ์ต๋๋ค..
๋ง์นจ ์ธ์ ์ค์ ๊ด๋ จ ์ธ์ ์ด ์๋ ๊ฒ ๊ฐ์ ๊ฑฐ๊ธฐ์๋ถํฐ ์์ํด๋ณผ ๊ฒ ๊ฐ๋ค์!
์๋๋ ํ๋ ์์ํฌ์์ ์ ๊ณตํ๋ ํํ์ trait๋ง ์ฌ์ฉํ ์ ์์์ง๋ง, ์ด์ ๋ ์ปค์คํ ํ์ฌ ๋ง๋ค ์ ์๋ค! ๋ผ๋ ๊ฒ์ด ํต์ฌ์ธ ๊ฒ ๊ฐ์ต๋๋ค.
Animated Symbol Images
์ ํ์ ์์ด์ฝ์ SF Symbols๋ฅผ ํตํด ์ ๊ณตํ๊ณ ์์ฃ ?
์ด ์์ด์ฝ๋ค์ ์ฌ์ฉํ๋ฉด ์ถ๊ฐ์ ์ธ ๋ ธ๋ ฅ ์์ด ์ฑ ์ ๋ฐ์ ์ผ๋ก ํต์ผ๋ ์ง๊ฐ์ ๋ผ ์ ์๋ ๊ฒ์ด ํฐ ์ฅ์ ์ ๋๋ค.
์ด์ ์ด SF Symbols์ ์ ๋๋ฉ์ด์ ์ด ์ถ๊ฐ๋๋ค๊ณ ํ๋ค์.
์ฌ์ง์ด ๊ธฐ๋ณธ์ผ๋ก ์ ๊ณต๋๋ Symbol ์ธ์๋ ์ปค์คํ Symbol์๋ ์ ์ฉํ ์ ์๋ค๊ณ ํฉ๋๋ค.
๊ทธ๋์ ์ด๋ป๊ฒ ํ๋?.. ๊ธฐ๋ณธ์ ์งฑ ์ฝ์ต๋๋ค.
self.imageView.addSymbolEffect(.bounce)
์ด๋ ๊ฒ .bounce
์ดํํธ๋ฅผ ์ถ๊ฐํด์ฃผ๋ฉด ํ ๋ฒ bounce ๋ฉ๋๋ค.
ใ ใ ใ ใ ใ ๊ท์ฝ์ง ์๋์..
self.imageView.addSymbolEffect(.variableColor.dimInactiveLayers)
self.imageView.removeSymbolEffect(ofType: .variableColor)
.bounce
์๋ ๋ค๋ฅด๊ฒ .variableColor
๋ ์ดํํธ๋ฅผ ์ ๊ฑฐํด์ค ๋๊น์ง ๋ฐ๋ณต๋ฉ๋๋ค.
์ด๋ ๊ฒ์!
์ด ์ธ์๋ ์ฌ๋ฌ๊ฐ์ง ์ดํํธ๋ค์ด ์์ต๋๋ค.
์ด ๋ด์ฉ ๋ํ ๋ณ๋์ ์ธ์ ์ผ๋ก ์ค๋น๋์ด ์๋ค๊ณ ํ๋ค์.
๊ฑฐ๊ธฐ์ ๋ ์์ธํ ์ดํด๋ณด๋๋ก ํฉ์๋ค!
Empty States
์๊ฐ์น๋ ๋ชปํ ๊ธฐ๋ฅ์ด UIKit์ ์ถ๊ฐ๋์์ต๋๋ค.
๋ฐ๋ก ๋น์ด์๋ ํ๋ฉด Configuration!
๊ทผ๋ฐ ๊ทธ ์ ์ ์ด๊ฒ ์ข ๋ด์ฃผ์ธ์..
๐ ๐ ๐ ๋๋ฌด ๊ท์ฌ์ฐ์ โฆ
๊ทธ๋์ ์ด๋ ๊ฒ ๊ท์ฝ๊ฒ ์๊ฐํ์ ๋ด์ฉ์ด ๋ญ๋๋ฉด์..
์ด๋ ๊ฒ ์ปจํ ์ธ ๊ฐ ์๋ ๋น์ด์๋ ํ๋ฉด ์ ๋๋ค.
์ ๋ง ์์ํ๊ฒ ์ปจํ ์ธ ๊ฐ ์๊ฑฐ๋ ๋คํธ์ํฌ ์ค๋ฅ๋ก ์ธํด ๋ถ๋ฌ์ฌ ์ ์๋ ๋ฑ ํ๋ฉด์ ์๋ฌด๊ฒ๋ ํ์ํ ์ ์๋ ๊ฒฝ์ฐ ๋ค์ด ์์ฃ ?
var config = UIContentUnavailableConfiguration.empty()
config.image = UIImage(systemName: "star.fill")
config.text = "No Favorites"
config.secondaryText = "Your favorite translations will appear here."
viewController.contentUnavailableConfiguration = config
๊ทธ๋ด ๋ ์ด๋ ๊ฒ ๊ฐ๋จํ๊ฒ ๋น์ด์๋ ํ๋ฉด์ ๋ํ ํธ๋ค๋ง์ ํด์ค ์๊ฐ ์๊ฒ ๋์์ต๋๋ค.
ViewController
๋ด๋ถ์์ ์ฌ์ฉํ ์ ์๋ ๋ฐฉ๋ฒ์์?
updateContentUnavailableConfiguration(using state:)
๋ฉ์๋๋ฅผ override
ํด์ ์ฌ์ฉํด์ฃผ๋ฉด ๋ฉ๋๋ค.
override func updateContentUnavailableConfiguration(
using state: UIContentUnavailableConfigurationState
) {
var config: UIContentUnavailableConfiguration?
if self.searchResults.isEmpty {
config = .search()
}
self.contentUnavailableConfiguration = config
}
์ด๋ ๊ฒ contentUnavailableConfiguration
์ ๊ต์ฒดํด์ฃผ๋ ๋ก์ง๋ค์ ๋ฃ์ด์ฃผ๊ณ , ๋ณ๊ฒฝ์ด ํ์ํ ๊ณณ์์
self.setNeedsUpdateContentUnavailableConfiguration()
๋ฅผ ํธ์ถํด์ฃผ๋ฉด ๋ฉ๋๋ค.
์์ฃผ ๊ฐ๋จํ์ฃ !
Internationalization
๋ค์ ํํธ๋ ๊ตญ์ ํ์ ๋๋ค.
์ด ํํธ๋ ์ฌ์ค ์ ํ ๊ธฐํ๊ฐ ๋ง์ง ์์ ๊ฒ ๊ฐ์์ ๊ด์ฌ ์๋ ๋ถ์ผ๋ง ์ดํด๋ณผ๊ฒ์..
Wrapping and Hyphenation
์ ํํธ๊ฐ ์ฌ์ค ์๋ ๋ฌธ์์ ๊ด๋ จ๋ ๋ด์ฉ์ด๋ผ ํ .. ํ๋ฉด์ ๋ณด๊ณ ์์๋๋ฐ์.
์ด ํํธ๋ก ๋์ด์ค๋ฉฐ ํ๊ตญ์ด๊ฐ ์ธ๊ธ๋ผ์ ์! ํ๋ฉด์ ๋ค์ ์ง์คํด์ ๋ณด๊ฒ ๋์์ต๋๋ค.
์ค๊ตญ์ด, ๋ ์ผ์ด, ์ผ๋ณธ์ด, ๊ทธ๋ฆฌ๊ณ ํ๊ตญ์ด์ line-breaking ์ ํฅ์์ด ์๋ค๊ณ ํ๋ค์.
๋๋ถ๋ถ์ ๊ฒฝ์ฐ์๋
let label = UILabel()
label.text = "์๋
ํ์ธ์!"
label.traitOverrides.typesettingLanguage = Locale.Language(identifier: "ko")
์ด๋ ๊ฒ typesettingLanguage
trait์ ์ค์ ํด์ฃผ๋ ๊ฒ ๋ง์ผ๋ก๋ line-height์ hyphenation rule์ ์ค์ ํด์ค ์ ์๋ค๊ณ ํ๋ค์.
UIImage
๋ฅผ ๋ฐ์์ฌ ๋๋ Locale์ ๋ฐ๋ผ ๋ค๋ฅธ ํฌ๊ธฐ๋ฅผ ๋ฐ์์ฌ ์ ์๋ค๊ณ ํฉ๋๋ค.
UIImage
์ font
ํฌ๊ธฐ๊ฐ UILabel
์ ํฌ๊ธฐ์ ๋ง์ง ์๋ ๊ฒฝ์ฐ์ ์ง์ ๊ฐ์ ๋น๊ตํด๊ฐ๋ฉฐ ๋ฃ๋๋ผ ๊ณ ์ํ ๊ฒฝํ์ด ์๋๋ฐ, ๊ทธ ๋ฌธ์ ๊ฐ ํด๊ฒฐ๋ ๊ฒ ๊ฐ์ต๋๋ค.
let locale = Locale(languageCode: .korean)
imageView.image = UIImage(
systemName: "character.textbox",
withConfiguration: UIImage.SymbolConfiguration(locale: locale)
)
์๋์ผ๋ก ๋๋ ๊ฒ์ ์๋๊ณ , ์ด๋ ๊ฒ locale
์ configuration
์ผ๋ก ์ ๊ณตํด์ฃผ๋ ๊ฒ์ผ๋ก ์ ์ฉ์ด ๊ฐ๋ฅํฉ๋๋ค.
General Enhancements
์์ดํจ๋ ๋ถ๋ถ์ ์ฐ์ ์ญ ๋์ด๊ฐ๊ณ โฆ
์ ๋ฐ์ ์ธ ํฅ์ ๋ถ๋ถ์ ์ดํด๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
CollectionView Improvements
CollectionView
๊ฐ ์ฑ๋ฅ์ ์ผ๋ก ๋! ํฅ์๋์๋ค๊ณ ํ๋ค์..
๋๋ต 10000๊ฐ์ ์์ดํ ์ด ์์ ๋, iOS 16์ ๋๋นํด์ ๋๋ฐฐ์ ๋ ๋น ๋ฅด๋ค๊ณ ํฉ๋๋ค.
10000๊ฐ์ ์์ดํ ๊น์ง ํํํ ์ผ์ด ์์๊น..? ์ถ๊ธด ํ๋ฐ.. ์๋ฌดํผ ๋นจ๋ผ์ ์์ข์ ๊ฑด ์์ผ๋๊น์?
์ด ์ต์ ํ๋ Snapshot
์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ, batchUpdate
๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ ๋ชจ๋์๊ฒ ํต์ฉ๋๋ค๋ค์!
๊ทผ๋ฐ ์ด๋ป๊ฒ ํ ๊ฑด์ง๋ ์ค๋ช ์ ์ํด์.. ๊ทธ๋ฅ ๊ทธ๋ ๋ค๊ณ ์๊ณ ๋์ด๊ฐ๋ผ๋ ๊ฒ ๊ฐ์ต๋๋คโฆ
๋ค์์ผ๋ก๋ CompositionalLayout ์ ํฅ์์ ์ ๋๋ค.
์ ๊ฐ ์์ฃผ ์ฌ๋ํ๋ CompositionalLayout
.. ์ผ๋ง๋ ๋ฐ์ ํ๋ ๋ณผ๊น์?
์ ์ฉ ์์๋ก ์ ํ์ด ๊ฐ์ ธ์จ ์์ดํจ๋์ ๊ฑด๊ฐ ์ฑ์ ๋๋ค.
๋ Item ๋ชจ๋ .estimated
๋ ์ด์์ ์ฌ์ด์ฆ๋ก ๊ตฌํ๋์๋ค๊ณ ํ๋๋ฐ์.. ์ ๋ณด๋ฉด ๋ ์์ดํ
์ ๋์ด๊ฐ ๋ค๋ฆ
๋๋ค.
๊ทธ๋ฌ๋๊น Item ์์ฒด์ ์ฌ์ด์ฆ๊ฐ ๋ค๋ฅด์ง๋ง, ํ๋์ ๊ทธ๋ฃน์ผ๋ก ๋ฌถ์ฌ์๊ธฐ ๋๋ฌธ์ ํ๋จ ์์ญ์ด ๋จ์์๋ ๋ชจ์ต์ธ ๊ฒ์ด์ฃ .
์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ์๋ก์ด layoutDimension
์ด ์๊ฐ๋์์ต๋๋ค.
uniformAcrossSiblings
์ด๋ผ๋ ์ด๋ฆ์ผ๋ก ๋ฑ์ฅํ๋ค์.
NSCollectionLayoutDimension.uniformAcrossSiblings(estimate:)
ํ๋์ ๊ทธ๋ฃน์์ ์๋ ์์ดํ ๋ค์ด ๊ฐ์ฅ ํฐ ์์ดํ ์ ํฌ๊ธฐ์ ๋ง์ถฐ์ง๋ ๊ฒ ์ ๋ณผ ์ ์๋ค์.
์ด๋ ๊ฒ ๋ ์ง์ ์ด ๋ฌ๋ผ์ ๋ถํธํ๋ ๋ ์ด์์์
๊ทธ๋ฃน ๋ด์ ๊ฐ์ฅ ํฐ ์์ดํ ์ ๋ง์ถฐ ๋์ด๋ฅผ ํต์ผ ์ํฌ ์ ์๊ฒ ๋์์ต๋๋ค.
ํธ์โฆ ๐
Spring Animation Parameters
Spring Animation์ ํ๋ผ๋ฏธํฐ๋ฅผ ๋ ๊ฐ์ง๋ก ์ค์ด๋ ํฅ์์ด ์๋ค๊ณ ํฉ๋๋ค.
duration ๊ณผ bounce ์ด๋ ๊ฒ ๋ ๊ฐ์ง๋ก์.
duration
์ ์ ๋๋ฉ์ด์
์ ์ฒด์ ๊ฑธ๋ฆฌ๋ ์๊ฐ์ด ์๋๋ผ ๋ณํ ์์น์ ๋ค๋ค๋ฅด๋ ์๊ฐ์
๋๋ค. bounce
์๋ ์๋ฒฝํ๊ฒ ๋
๋ฆฝ์ ์ผ๋ก ๋์ํ๋ค๊ณ ํ๋ค์.
bounce
๋ ๋ง ๊ทธ๋๋ก ํ๊ธฐ๋ ์ ๋๋ฅผ ์กฐ์ ํ ์ ์๋ ํ๋ผ๋ฏธํฐ ์
๋๋ค.
์ด ๋ ํ๋ผ๋ฏธํฐ๋ UIView.animate
์ ๋ฐ๋ก ์ ์ฉํ ์ ์์ต๋๋ค.
UIView.animate(springDuration: 0.5, bounce: 0.5) {
self.circle.center.x += 100
}
์ด ๋ ํ๋ผ๋ฏธํฐ๋ Optional ํ๋ผ๋ฏธํฐ๋ผ์
UIView.animate {
self.circle.center.x += 100
}
์ด๋ ๊ฒ ํ๋ผ๋ฏธํฐ ์์ด ์ฌ์ฉํ๊ฒ ๋๋ฉด ์์คํ ์ด ์ ํด๋ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ๋์ํฉ๋๋ค.
Text Interactions
ํ ์คํธ ์ ๋ ฅ ์ปค์์ ํ ์คํธ ์ ํ์ ์๋ก์ด API๋ค์ด ์ ๊ณต๋ฉ๋๋ค.
์ด์ UITextInteraction
์ ํต์งธ๋ก ๊ฐ์ ธ์ ์ ์ฉํ๋ ๋์ , ์ ํํ ํ
์คํธ์ ๋ํ UI๋ง ์ฌ์ฉํ ์ ์๋ค๊ณ ํฉ๋๋ค.
์๋ก์ด API๋ค์ UITextViewDelegate
๋ฅผ ์ฑํํ๋ฉด์ ์ฌ์ฉํ ์ ์์ผ๋ฉฐ, link
์ text attachments
๋ฅผ ๋ ์์ ์์ฌ๋ก ์ฌ์ฉํ ์ ์๋๋ก ํ๋ค๊ณ ํฉ๋๋ค.
์ถ๊ฐ๋ก link
๊ฐ ์๋ ํ
์คํธ์ ๋ํด์๋ ์ธํฐ๋์
์ก์
์ ์ถ๊ฐํ ์ ์๋ API๋ ์ถ๊ฐ๋์๋ค๊ณ ํ๋ค์!
๋ค๋ง ์ด ๋ถ๋ถ์ ์ ๊ฐ ์ ์ฉํด๋ณธ ์ ์ด ์์ด์ ์ ๋๋ก ์ดํดํ ๊ฒ์ธ์ง ๋ชจ๋ฅด๊ฒ ๋ค์..
Default StatusBar Style
์ด๋ฐ ๊ฒฝ์ฐ ์์ฃผ ๋ง์ ๊ฒ๋๋ค.
์ด ๊ฒฝ์ฐ ๋ผ์ดํธ ๋ชจ๋๋ผ์ ๊ฒ์ ์์ StatusBar๊ฐ ์ฌ์ฉ๋๊ณ ์์ต๋๋ค.
ํ์ง๋ง ์ปจํ ์ธ ๋ฅผ ์๋ก ์คํฌ๋กคํ๋ฉด..?
์จ์.. ์ด๋ ๊ฒ ์ปจํ ์ธ ์ StatusBar๊ฐ ๊ฒน์ณ๋ณด์ด๋ฉด์ ์๋๋ผ๋ฉด ๊ฒ์ ์์ StatusBar๊ฐ ์๋ณด์ด๊ฒ ๋๊ฒ ์ง๋ง,
override var preferredStatusBarStyle: UIStatusBarStyle {
return .default
}
์ด๋ ๊ฒ .default
๋ก ์ค์ ํด๋๋ฉด ์์์ ๋ค์ ๋ฐฐ์น๋ ์ปจํ
์ธ ์ ๋ฐ๋ผ ์์์ ๋ฐ๊พผ๋ค๊ณ ํ๋ค์.
์ฌ์ง์ด ์ด ๋ณํ๋ ์์ชฝ์ด ๋ณ๊ฐ๋ก ์๋ํฉ๋๋ค.
์์ฃผ ๊ตฟ! ๐
Drag and Drop Enhancements
์ด ๋ถ๋ถ์ ์ง์ ๋ณด๋๊ฒ ๋น ๋ฅผ ๊ฒ ๊ฐ์์!
์ด์ ๋๋๊ทธ & ๋๋กญ์ด ๊ฐ๋ฅํ ์ปจํ ์ธ ๋ ์ปจํ ์ธ ์ ์ข ๋ฅ์ ๋ฐ๋ผ ์ฑ ์์ด์ฝ์ ๋๋กญํ๋ ๊ฒ ๋ง์ผ๋ก๋ ํน์ ์ก์ ์ ํ ์ ์์ต๋๋ค.
Info.plist
์ CFBundleDocumentTypes
์ ํด๋น ํ์ผ์ ํ์์ด ์ง์ํ๋ ์ง๋ฅผ ์ค์ ํด์ฃผ๋ฉด ๋ฐ๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค.
์ด๋ ๊ฒ ์ค์ ๋ ํ์์ ํ์ผ์ UIScene
delegate ์ฝ๋ฐฑ์ ์ํด ์ฒ๋ฆฌ๋๋ค๊ณ ํ๋ค์!
ISO HDR Image Support
UIKit์์ ์ด์ UIImageView
๋ UIGraphicsImageRenderer
์์ ISO HDR ์ด๋ฏธ์ง๋ฅผ ์ฝ๊ฒ ์ฌ์ฉํ ์ ์์ต๋๋ค.
์ด ๋ถ๋ถ๋ ๊ด๋ จ ์ธ์ ์์ ์์ธํ๊ฒ ๋ค๋ฃฌ๋ค๊ณ ํฉ๋๋ค..
PageControl
UIPageControl
์ ์๋ ์ ํ๋๋ ๋ฐฐ๋๋ก ๋ง์ด ์ฐ์ด๊ณ ์์ฃ .
๊ทธ ์ฐ์์๋ฅผ ๊ฐํํ ์ ์๋๋ก UIPageControl
์ ํ์ด๋จธ ๊ฐ ์ถ๊ฐ๋์์ต๋๋ค.
๋จ์ํ ์ ๋ง ์๋ ๊ฒ์ ๋์ด ์ด์ ํ์ฌ ํ์ด์ง๊ฐ ์ผ๋ง๋ ์งํ๋์๋์ง ๋ฅผ ์๊ฐ์ ์ผ๋ก ์ ๊ณตํ๋ค์.
let timerProgress = UIPageControlTimerProgress(preferredDuration: 10)
pageControl.progress = timerProgress
timerProgress.resumeTimer()
UIPageControl
์ ์๋ก์ด progress
ํ๋กํผํฐ๋ฅผ ํ์ฉํด์ ์ฝ๊ฒ ์ฌ์ฉํ ์ ์์ต๋๋ค.
๊ทธ๋ฆฌ๊ณ ๋ฌด๋ คโฆ ๋นํธ์ธ ํ์ด๋จธ ๊ฐ ์๊ฒผ๋ค๊ณ ํด์..
ํ์ด๋จธ๊ฐ ๋ ๋๋ง๋ค ๋ค์ ํ์ด์ง๋ก ์์์ ๋์ด๊ฐ๋ ๊ฒ์ ๋ฌผ๋ก ์ด๊ณ ,
myTimer.addPeriodicTimeObserver { timer in
progress.currentProgress = Float(timer.seconds / timer.duration)
// ..
}
์ด๋ ๊ฒ ์ง์ progress
๋ฅผ ์ค์ ํด์ค ์๋ ์์ด์!
์ด์ ์๋ ๋ฌดํ ์คํฌ๋กค ๋ฐฐ๋๋ฅผ ์์ฃผ ์ฝ๊ฒ ๊ตฌํํ ์ ์๊ฒ ๋ค์.
Palette Menus
์๋ ์ง์ง ์ด๋ถ ์ ์ด๋ ๊ฒ ๊ท์ฌ์ฐ์ ๊ฑด๋ฐ์..
์๋ฌดํผ..
์ด๋ฐ ์์์ ์ ํํ๋ ๋ฉ๋ด๊ฐ ์ง๊ธ๋ ์ด๊ณณ์ ๊ณณ์ ์์์ฃ ..?
์ด์ Palette
๋ฉ๋ด๋ฅผ ๊ธฐ๋ณธ์ ์ผ๋ก ์ ๊ณตํ๋ค๊ณ ํฉ๋๋ค.
UIMenu(options: [ .displayInline, .displayAsPalette ], children: [ ... ])
์ด๋ ๊ฒ UIMenu
์ ๋ฃ์ด์ฃผ๋ ๊ฒ์ผ๋ก ๊ฐํธํ๊ฒ ์ฌ์ฉํ ์ ์์ต๋๋ค.
์์ ๋ฟ๋ง ์๋๋ผ
UIAction(image: UIImage(systemName: "heart.fill"), state: .on) { ... }
์ด๋ ๊ฒ ์ด๋ฏธ์ง๋ ๋ฃ์ด์ค ์ ์๋ค์.
์ด๋ฏธ์ง์ ๊ฒฝ์ฐ .on
์ํ์ผ ๋ tintColor
๋ก ํ์ด๋ผ์ดํธ ๋๋ค๊ณ ํฉ๋๋ค.
์ฌ๊ธฐ๊น์ง๊ฐ โWhatโs new in UIKitโ ์ธ์ ์ ๋ด์ฉ์ด์์ต๋๋ค.
Preview์ StatusBar, Progress๊ฐ ์ ๋ชฉ๋ PageControl..
๋ง์์ ๋๋ ๋ด์ฉ๋ค์ด ์๋ฉ ์์๋ค์. ๐
๋ค๋ฅธ ์ธ์ ๋ ์ผ๋ฅธ ๊ณต๋ถํ๋ฌ ์ถ๋!
References