본문 바로가기

iOS - 실무관련92

@Binding - 데이터 연동 이번 글은 이전 글의 코드를 이어서 진행하겠다. @Binding을 이용해서 다른 View에서도 데이터를 연동할 수 있도록 해보자. 1. @Binding을 사용하고 다른 View에서 해당 변수를 사용해야하기 때문에 Private를 쓰지 않고 변수를 선언하자. //MARK: 데이터를 연동 @Binding var isActivated: Bool 2. init을 사용해서 기본값을 설정해주자. //MARK: 생성자 - 기본값 설정과정 init(isActivated: Binding = .constant(true)) { _isActivated = isActivated } 3. Bool 값에 따라서 속성을 변경해보자. import SwiftUI struct MyVStackView: View { //MARK: 데이터를 .. 2022. 7. 12.
@State - 상태변화 감지 이번 글은 이전 글의 코드를 이어서 진행하겠다. 1. 탭 제스처를 사용자가 했을 때 HStack의 padding, Color가 변경되게 만들어보자. 우선 제스처를 했는지 확인하는 과정이 필요하다. 따라서 HStack의 속성에 탭 제스처를 했는지 확인후 탭 제스처를 했다면 해당 로직을 실행하는 속성을 추가해보자. .onTapGesture { //코드 } 내부에 탭을 했다면 "탭을 했습니다!" 라고 print 되도록 코드를 작성해보자. import SwiftUI struct ContentView: View { var body: some View { HStack { MyVStackView() MyVStackView() MyVStackView() } .padding(10) .background(Color.red.. 2022. 7. 12.
SwiftUI와 친해지기 프로젝트 구성 새로운 프로젝트를 만들 때 Stoyboard가 아니라 SwiftUI를 선택해서 생성하면 아래와 같은 파일들이 뜨게 된다. 프로젝트 이름App.swift ContentView.swift Assets.xcassets Preview Content Preview Assets.xcassets 1. 프로젝트 이름App.swift SwiftUI로 된 프로젝트를 생성하면 Stoyboard로 된 프로젝트와 다른 점이 있다. AppDelegate와 SceneDelegate가 없다는 점이다. 물론 애플도 생각 없이 없애진 않았다. AppDelegate와 SceneDelegate의 역할은 "프로젝트 이름App.swift"의 파일에서 주어진 메서드를 통해서 해결할 수 있다. (자세한 내용은 추후 배우면서 알아보겠.. 2022. 7. 12.
userNotificationCenter의 willPresent 함수를 백그라운드에서 실행하는 방법은 뭘까? (미해결) 현재의 상황: willPresent를 백그라운드에서 실행되도록하여 알람이 실행되었을 때 소리를 울리게 한다거나, 진동이 울리도록 만들려고 한다. 문제: willPresent가 백그라운드에서 실행되지 않기 때문에 소리, 진동을 울리게 할 수 없다. 해결: 2022. 7. 7.
label 행간 조정 func labelSetting(label: UILabel) { label.numberOfLines = 0 // Label의 글자 줄을 제한두지 않음. let attrString = NSMutableAttributedString(string: label.text ?? "") // 텍스트에 대한 관련 속성이 있는 문자열 let paragraphStyle = NSMutableParagraphStyle() // 문단 스타일 속성의 하위 속성 값을 변경하는 개체 paragraphStyle.lineSpacing = 3 // 행간 조정 attrString.addAttribute(NSAttributedString.Key.paragraphStyle, value: paragraphStyle, range: NSMakeRa.. 2022. 7. 5.
dismiss를 하고 이벤트 발생 시키는 방법 참고: 스택오버플로우 화면전환시 이벤트를 발생시키려면 생명주기를 활용해서 해당 이벤트를 실행시키면 된다. 하지만 dismiss를 사용하는 경우 생명주기를 거치지 않는다. (.FullScreen은 제외) 이런 상황에서 이벤트는 어떻게 발생시켜야할까? 1. 첫번째 ViewController에 프로토콜을 정의한다. protocol ViewControllerDelegate: UIViewController { func refresh() } 2. 두번째 ViewController에 delgate를 만든다. weak var delegation: ViewControllerDelegate? 3. delegate = self를 통해서 delegate 지정 delegation = self 4. 프로토콜을 채택하고, 해당 프.. 2022. 6. 23.
Notification push 앱에서 알람 거부에서 허용으로 설정 결론을 말하자면 거의 불가능이다. '거의'라고 말한 이유는 방법이 하나 있기 때문이다. 알람 거부에서 허용으로 바꾸려면 아이폰 설정에 들어가서 허용으로 바꾸라고 해야한다. (아래의 사진확인) 따라서 앱 자체에서 거부된 권한을 허용으로 변경할 수는 없다. 2022. 6. 14.
Delegate 패턴 아래의 글은 해당 블로그를 참고하여 작성하였습니다. (+ 다른 블로그) 1. Delegate는 무엇인가? Delegate란 어떤 객체가 해야 할 일을 부분적으로 확장해서 대신 처리한다. 2. Delegate는 어디에 사용되는가? Delegate는 두 가지만 기억하면 된다. 1. 처리하라고 시키는 객체 2. 대신 처리해줄 객체 0. 상황 상황: 여러곳에서 사용할 수 있는 메시지 창을 만들려고한다. 메시창에는 버튼이 있고 해당 버튼을 누르면 ViewController는 무슨 버튼을 눌렀는지 확인해서 그 버튼이 이벤트가 발생하면 해야하는 일들을 처리해야 한다고 한다. 1. 처리하라고 객체 우선 대신 처리하라고 시키는 객체를 만들기 전에 우리는 객체의 프로토콜을 선언해주는 작업이 필요하다. (이후 대신 처리해줄.. 2022. 6. 12.
Exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:] 에러 위치 확인하기. "Exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]" 이 에러를 접하게 되면 어디에서 에러가 발생했는지는 나타나지 않고 아래처럼 @main에서 오류 문구가 나타난다. 따라서 이번에는 break point navigator를 이용하여 해당 에러의 위치를 파악하고 에러를 해결해보자. (에러 해결법은 각자가 구현하자.) 1. Break Point Navigator를 클릭하고 아래에 있는 +버튼을 눌러준다. (사진 참고) 2. Exception BreakPoint를 클릭해주고 Exception 언어는 All로 설정해준다. 3. 그리고 실행을 하게 되면 Exception 오류가 발생하는 위치에 BreakPoint가 잡히게된다. 이제 여.. 2022. 6. 12.
textView행간 조절, 정렬, 폰트, 폰트 사이즈 설정하기 let explainText = "안녕하세요 \n iOSoo입니다." let style = NSMutableParagraphStyle() //단락 스타일 속성의 하위 속성 값을 변경하기 위한 개체입니다. style.lineSpacing = 5 //text 행간 조절 style.alignment = .center //text 정렬 let attributes = [NSAttributedString.Key.paragraphStyle : style] explanationTextView.attributedText = NSAttributedString(string: explainText, attributes: attributes) explanationTextView.font = .systemFont(ofSize: .. 2022. 6. 8.
Pinch 제스처로 이미지 확대 축소하기 https://zeddios.tistory.com/343 Pinch 기본적인 코드는 해당 블로그 참고해서 작성 https://github.com/iOS-junsoo/Pinch 깃헙주소 1. 제한 없이 이미지 확대 축소하기 import UIKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() myView.isUserInteractionEnabled = true } var recognizerScale: CGFloat = 1.0 var maxScale: CGFloat = 2.0 var minScale: CGFloat = 1.0 @IBOutlet weak var myView: UIView! @IB.. 2022. 6. 5.
라이브러리 Demo 파일 실행(Xcode) 오픈 라이브러리를 사용하려면 블로그를 참고해서 라이브러리를 사용해도 문제는 없다. 하지만 라이브러리를 더 잘 사용하기 위해서는 해당 라이브러리의 데모 파일을 살펴보면서 내가 원하는 스타일의 라이브러리를 찾아서 참고하면서 코드를 참고할 수 있다. 해당 설명은 Charts 라이브러리를 예시로 설명하고 있다. 1. 해당 라이브러리 GitHub로 들어가서 Zip 파일을 다운 받는다. (Download ZIP) 2. Zip파일을 압축해제하고 해당 파일에서 xcworkspace파일을 실행한다. 3. 프로젝트를 열면 1번 사진과 같이 되어있을텐데 2번 사진처럼 변경한 후 실행한다. 2022. 6. 5.
Bars - Tab Bars Tab Bars 탭바는 앱화면 아래 나타나 앱의 다른 섹션으로 빠르게 이동할 수 있게 도와준다. 탭바는 기본적으로 투명하나 배경 색상값을 가질 수도 있으며, 화면의 어떤 모드(가로/세로)에도 동일한 높이를 유지하고, 키보드가 나왔을 땐 가려진다. 탭바는 어떤 수의 탭도 포함할 수 있긴 하지만, 탭은 기기 크기나 모드에 따라 보여지는 탭의 개수가 달라진다. TIP💡 둘 다 앱화면의 아래에 나오기 때문에 탭바와 툴바의 차이를 알아두는 것이 좋다. 탭바는 앱의 다른 섹션으로 이동할 수 있게 한다. 반면 툴바는 현재 맥락과 관련된 액션을 수행하기 위한 버튼을 포함한다. 아이템을 삭제하거나 만들고, 주석을 추가하거나 사진을 찍는 것이다. 탭바와 툴바는 절대 같은 화면에서 함께 나오지 않는다. 탭바는 앱 수준에서의.. 2022. 5. 25.
Bars - Navigation Bars Navigation Bars 네비게이션 바는 앱 화면의 최 상단, 상태 바의 아래에 위치한다. 새로운 화면이 나오면 뒤로가기 버튼이 네비게이션 왼쪽에 보이게된다. 해당 버튼에는 이전 화면 라벨이 달려있다. (예를 들어 1번 화면에서 2번 화면으로 갔을 때 '< 1번화면' 이런 식으로) 또한 때때로 네비게이션의 오른쪽 부분에는 수정, 완료와 같은 컨트롤이 포함되어 있으며, 이를 통해 현재 보고있는 화면의 컨텐츠를 관리할 수 있다. 네비게이션 바는 반투명하고 배경 색상값을 조정할 수 있으며 키보드가 화면에 뜨거나 제스처 발생시, 혹은 뷰의 크키가 조정되었을 때 숨김처리 될 수 있다. 더 몰입감 높은 경험을 위해 일시적으로 네비게이션 숨겨보자. 예를 들어, 사진 앱에서 풀스크린 사진 뷰에서 네비게이션 바와 다.. 2022. 5. 25.
SnapKit 라이브러리의 정식 깃허브 주소는 여기이다. 왜 사용할까? Autolayout을 코드로 작성하려면 NSLayoutConstraint를 직접 지정해주며 하나하나 제약을 적용해 주어야한다. 이렇게 코드를 구성하면 복잡도는 올라가고 가독성은 떨어진다. 그렇기 때문에 SnapKit을 사용한다. 어떻게 사용할까? 1. SnapKit을 import 해주고 View를 만들어준다. import UIKit import SnapKit class ViewController: UIViewController { let box = UIView() override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. } }.. 2022. 5. 23.
방법2) 라이브러리 가져오기 - SPM(Swift Package Manager) Cocoa Pod을 두고 SPM을 이용하는 이유는 간단해서 그렇다. 하지만 장점이 있으면 단점도 있다. 단점은 지원하는 라이브러리가 많지 않다. 1. Project - TARETS - Frameworks, Libraries, and Embedded Content에서 + 를 클릭해준다. 2. Choose frameworks and libraries to add라는 팝업창이 뜨는데 여기서 하단 드롭박스 메뉴에서 Swift Package Manager를 선택 3. Choose Package Repository 라는 창에서 SPM을 지원하는 라이브러리를 주소를 입력후 Add Package를 누른다. 4. next 화면들에서 필요한 부분은 각자 체크하고 마무리 되면 Finish를 누른다. 2022. 5. 23.
방법1) 라이브러리 가져오기 - Cocoa Pod 1. 해당 프로젝트로 터미널 열기 2. pod init 해주기 pod init 3. 2번 과정으로 만들어진 pod file 열기 open -e podfile 4. 라이브러리 연결하기 podfile을 열고 pod '라이브러리 이름' 을 작성후 저장한다. pod 'SnapKit' # Uncomment the next line to define a global platform for your project # platform :ios, '9.0' target 'Project 01 - GoodAsOldPhones' do # Comment the next line if you don't want to use dynamic frameworks use_frameworks! # Pods for Project 01 - .. 2022. 5. 23.
원형 View 만들기 extension UIView { @IBInspectable var borderWidth: CGFloat { set { layer.borderWidth = newValue } get { return layer.borderWidth } } @IBInspectable var cornerRadius: CGFloat { set { layer.cornerRadius = newValue } get { return layer.cornerRadius } } @IBInspectable var borderColor: UIColor? { set { guard let uiColor = newValue else { return } layer.borderColor = uiColor.cgColor } get { guard let .. 2022. 5. 22.
SceneDelegate에서 특정 ViewController 보여지게 만들기 self.window?.rootViewController = UIStoryboard(name: "스토리보드 이름", bundle: nil).instantiateViewController(withIdentifier: "VC이름") 위의 코드는 특정상황에서 앱을 들어갈 때 다른 ViewController가 present 되도록 만들때 나오게 만든다. 2022. 5. 8.
DatePickerView 24h 설정하기 DatePickerView로 시간을 설정할 때 12시간짜리와 24시간 짜리를 설정하고 싶을 때가 있을 것이다. 대부분 12시간을 기본 값으로 한다. 하지만 이때 AM과 PM을 없애려면 어떻게 해야할까? DatePickerView - Attributes inspector - DatePicker - Locale - English(Gibraltar)를 설정해주면 24시간으로 설정된다. 2022. 4. 17.
시작하는 Storyboard 변경하기 1. 기존 MainStoryboard의 is Initial View Controller를 해제해준다. 2. 변경할 Storyboard를 생성하고 is Initial View Controller를 체크해준다. 3. Info파일에서 Main storyboard file base name과 Storyboard Name을 변경할 Storyboard 이름으로 변경해준다. 2022. 4. 17.
Multi Thread [Thread vs Multi - Thread] 1. Thread란 (작업의) 실 / 흐름 / 시퀀스이다. 2. Thread의 속성 연속성 흐름 자율성 독립성 지금은 위의 말이 무슨 말인지 와닿지 않을 수 있다. 앞으로 글을 읽다보면 이해가 될 것이다. 설명하기전 우리가 앱을 만드는 방식을 살펴보면 아래의 사진처럼 UI를 제작하고 Logic을 구성하고 UI 또는 Data를 업데이트할 것이다. 이 때 Logic 구성과 UI/Data 업데이트를 우리는 앞으로 Task(작업단위)로 칭할 것이다. 수업을 한 예시로 Thread를 표현하면 아래의 사진처럼 표현할 수 있다. 아래의 사진을 보면 어색한 부분이 있는데 그 부분은 수업과 필기가 따로 행해지고 있다는 것이다. 위의 표현처럼 수업이 진행된다고 하면 선생님이.. 2022. 4. 16.
Tabbar 관련 변경 폰트변경 AppDelegate - didFinishLaunchingWithOptions 에서 폰트 변경 코드를 입력한다. func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // 탭바 폰트 설정 let appearance = UITabBarItem.appearance() let attributes = [NSAttributedString.Key.font:UIFont(name: "폰트 이름", size: 폰트사이즈)] appearance.setTitleTextAttributes(attributes as [NS.. 2022. 4. 16.
User Interaction - 3D Touch 3D Touch 지원되는 디바이스에서 사람들은 터치스크린에 여러 단계의 압력을 주어 추가적인 기능에 접근할 수 있다. 앱은 Context menu (또는 peek and pop)에서 터치한 아이템에 사용할 수 있는 액션을 보여줌으로서 사용자에게 반응할 수 있다. iOS 13와 그 이후 버전의 기기에서 3D 터치 지원여부와 관계없이 사용자는 터치후 홀드 제스처를 사용하여 Context menu를 열 수 있다. 3D 터치를 지원하는 기기에서는 위 기능을 사용하면 Context menu가 더 빠르게 보여진다. Home Screen Interaction iOS 13과 그 이후 버전에서 홈스크린의 앱 아이콘을 터치 후 홀드하면 앱에선 Context menu를 보여줄 수 있다. (3D 터치 지원 기기에선 메뉴를 보.. 2022. 4. 11.
App Architecture - Settings 몇몇 앱은 환경 설정 선택을 할 수 있는 방법을 제공해줘야 하지만, 대부분의 앱은 이를 피하거나 미룰 수 있다. 성공적인 앱들은 경험을 조정할 수 있는 몇몇 방법을 제공하면서, 대부분의 사용자에 잘 맞게 바로 작동할 수 있습니다. 당신이 시스템에서 어떤걸 얻을 수 있을지 추측해보자. 만약 사용자나 기기, 혹은 환경에 대한 정보가 필요하다면, 사용자에게 묻는 대신 시스템에서 찾아봐라. 예를 들어, 현재 위치를 표시하기 위해 사용자에게 우편번호를 입력하라고 요구하는 대신 현재 위치 정보를 사용하도록 허가를 요구해라. 앱 내에서의 환경 설정 옵션을 우선적으로 처리해라. 앱의 메인 화면은 꼭 필요하거나 자주 바뀌는 옵션을 표시하기 좋은 장소이다. 2차적인 화면엔 종종 바뀌는 옵션을 표시하는 것이 좋다. '설정'.. 2022. 3. 31.
App Architecture - Accessing User Data 사용자 개인 정보가 가장 중요하다. 사람들이 앱을 신뢰할 수 있도록 하려면 필요한 개인정보 보호 관련 데이터와 리소스, 사용 방법을 투명하게 공개하는 것이 중요하다. 다음과 같은 데이터들은 액세스 권한 요청이 필요하다. 위치, 건강, 재정, 연락처 및 기타 개인 식별 정보를 포함한 개인 데이터 이메일, 메시지, 캘린더 데이터, 연락처, 게임 플레이 정보, Apple Music 활동, HomeKit 데이터, 오디오, 비디오 및 사진 콘텐츠와 같은 사용자 생성 콘텐츠 Bluetooth 주변 장치, 홈 자동화 기능, Wi-Fi 연결 및 로컬 네트워크와 같은 보호된 리소스 카메라 및 마이크와 같은 장치 기능 iOS 14.5 및 iPadOS 14.5부터 사용자를 추적하거나 기기의 광고 식별자에 액세스 하려면 Ap.. 2022. 3. 31.
App Architecture - Navigation 사용자들은 앱의 네비게이션이 기대에 부응만 잘 한다면, 그 존재에 대해 잘 눈치채지 못한다. 당신은 네비게이션 바가 그 자체로 주의를 끌지 않으면서, 앱의 목적과 구조를 잘 지지하도록 해야한다. 자연스럽고 친숙하게 느껴져야 하되 화면에 가장 중요한 특징이 되거나, 내용으로부터 시선을 뺏도록 하지 말아야 한다. iOS에는 다음의 세가지 주된 스타일의 네비게이션이 있다. 위계 질서형 네비게이션(Hierarchical Navigation) 목적지 (화면)에 도달하기 위해 단 하나의 선택지를 만든다. 다른 목적지로 가기 위해선, 이전 단계를 되짚어 가야하거나 처음부터 다시 시작해 다른 선택을 해야만 한다. 설정(Settings)이나 메일에서 이 스타일의 네비게이션을 사용한다. 플랫(평면) 네비게이션(Flat N.. 2022. 3. 31.
App architecture - Modality Modality은 디자인 기술로, 사용자가 현재 접하는 내용(화면) 분리돈 모드에서 내용을 보여주며 이를 나가기 위해 확실한 동작을 요구한다. 내용을 Modality로 보여주면 다음과 같은 효과를 얻을 수 있다. 1. 사람들이 독립적인 작업이나 밀접하게 관련된 옵션들에 집중할 수 있게 해준다. 2. 사용자에게 매우 중요한 정보를 확실히 주고, 필요한 경우 바로 동작하도록 할 수 있게 한다. iOS는 앱 내 특정 상황에 사용할 수 있도록 alerts, activity views(share sheets) 와 action sheets를 제공한다. 앱에서 사용자 지정 모달 콘텐츠를 표시하려면 다음 Presentation 스타일 중 하나를 사용할 수 있다. 1. Automatic : 기본적인 프레젠테이션 스타일을.. 2022. 3. 30.
App architecture - Loading 콘텐츠가 로딩되고 있을 때, 빈 화면 혹은 정지 화면을 보여준다면 앱이 멈춘것 처럼 보일 수 있으며, 혼란스럽고 좌절감을 낳을 것이고, 잠재적으로 사용자들이 앱을 떠나버릴 수 있다. 현재 로딩 진행 중임을 확실히 하자. 최소한, 무언가 일어나고 있다는 것을 알리는 움직이는 스피너를 보여주자. 얼마나 기다려야 하는지 판단할 수 있는 확실한 진행 상황을 알려주면 더 좋다. 내용을 최대한 빨리 보여주자. 사용자들이 기대하는 화면을 보여주기 전에, 내용을 로딩하는데 기다리게 하지 말자. 즉시 화면을 보여주고, 내용(콘텐츠)가 아직 사용가능하지 않다는 것을 보여주기 위해 문자 입력창, 그래픽 혹은 애니메이션을 사용하도록하자 . 이 요소들은 내용의 로딩이 완료되면 교체된다. 가능하다면, 애니메이션이 재생되는 동안이.. 2022. 3. 29.
App architecture - Onboarding 온보딩이란? 유저들에게 새로운 인터페이스에 대해서 단계적으로 가르치거나 아주 간단한 인트로를 만들어 사용자가 지속적으로 서비스를 이용할 수 있도록 돕는 장치 또는 전략이다. 온보딩은 새로운 사용자들을 환영하고, 다시 돌아온 사용자들과 재 연결할 수 있게 한다. 빠르고 재밌으며, 교육적인 선택적 온보딩 경험은 사용자가 직접 경험하지 않고도 앱의 전반을 이해하는데 도움을 줍니다. 단순히 환경설정하는게 아닌, 앱을 즐길 수 있는 온보딩 화면을 제공하자. 사용자는 당신의 앱을 더 아는 기회에 감사할 수 있지만, 한편으론 그냥 작동하길 기대할 수도 있다. 세팅이나 동의 세부내역 등을 온보딩 경험에 포함시키지 말자. 빠르게 사용할 수 있도록 하자. 시스템이 시작화면을 앱의 첫 화면으로 바꾼 뒤에는, 사용자가 바로 .. 2022. 3. 29.