SeSAC_iOS_Day 15 | TIL

19212 단어 TILSeSACiOSSeSAC

👩‍💻 수업 & 추가 스터디

📂 RawString

  • 문자열 내에서 이스케이프 문자 혹은 경계 문자를 있는 그대로 사용하고 싶은 경우엔 문자열의 양 끝에 #을 붙이면 된다.
var notice = #"온라인 라이브 수업은 "Zoom"으로 진행합니다."#

➡️ 온라인 라이브 수업은 "Zoom"으로 진행합니다.

var notice = #"온라인 라이브 수업은 \Zoom\으로 진행합니다."#

➡️ 온라인 라이브 수업은 \Zoom\으로 진행합니다.

  • 하지만 이스케이프 문자의 기능을 사용하고 싶다면 \과 문자 사이에 #을 추가해주면 된다.
var notice = #"온라인 라이브 수업은 \#n\Zoom\으로 진행합니다."#

➡️ 온라인 라이브 수업은
\Zoom\으로 진행합니다.

  • 문자열 보간법을 사용하기 위해서도 동일하게 #을 추가해줘야 한다.
var onlineService = "WhaleOn"
var notice = #"온라인 라이브 수업은 \#(onlineService)으로 진행합니다."#

➡️ 온라인 라이브 수업은 WhaleOn으로 진행합니다.

📂 WKWebView & Search Bar

  • Web View를 띄우고 싶은 경우, WebKit View를 사용하면 된다.
  • Search Bar도 반드시 delegate 연결을 해줘야한다!
  • 검색 후 리턴 키 눌렀을 때 실행되는 메서드: searchBarSearchButtonClicked
    ➡️ UISearchBarDeleagte 프로토콜 내에 구현돼있는 메서드 중 하나
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
	// guard 문으로 searchBar에 입력된 문자열을 URL로 변경해주고 request 후 그 결과를 webView에 띄워준다.
        guard let url = URL(string: searchBar.text ?? "") else {
            print("ERROR")
            return
        }
        
        let request = URLRequest(url: url)
        webView.load(request)
    }

📂 App Transport Security Settings

  • 앱이 서버에 전송하는 데이터에 대한 보안 설정

  • HTTP 프로토콜을 사용하는 외부 서버와 통신하기 위해 설정

  • HTTPS(security): 데이터 패킷을 암호화여 전송하기 때문에 보안상 안정

  • 모든 도메인에 대한 HTTP 통신 허용: 보안상 권장되지 않는 방식

📂 UICollectionView

1. CollectionView 아웃렛 연결

@IBOutlet var tagCollectionView: UICollectionView!

2. CollectionView Protocol: UICollectionViewDelegate, UICollectionViewDataSource

  • numberOfItemsInSection
    - 총 아이템이 몇 개가 들어갈지 알려주는 코드
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 10
    }
  • 만약 한 viewController에 collectionView가 두 개 이상인 경우에는 아래와 같이 collectionView를 구별해줄 수 있다.
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        // 이 코드 대신 tag 설정해두고 사용해도됨
        return collectionView == tagCollectionView ? 10 : mainArray.count
    }
  • cellForItemAt: tableView에서 rowitem으로 변경된 것 외에는 코드 구성이 거의 동일하다.
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: TagCollectionViewCell.identifier, for: indexPath) as? TagCollectionViewCell else {
                return UICollectionViewCell()
            }
         return cell
    }

3. Deleagte, Datasource 연결

tagCollectionView.delegate = self
tagCollectionView.dataSource = self

4. XIB 등록

let secondNibName = UINib(nibName: TagCollectionViewCell.identifier, bundle: nil)
tagCollectionView.register(secondNibName, forCellWithReuseIdentifier: TagCollectionViewCell.identifier)

📂 UICollectionViewFlowLayout

상하좌우 여백(수직 섹션) + 셀과 셀 사이의 간격 + 셀 상하

FlowLayout instacne 생성

let layout = UICollectionViewFlowLayout()

itemSize 설정

// 각 셀과 셀 사이의 간격 설정
let spacing: CGFloat = 20
// 3개의 열로 세팅하기 위해서 전체 폭에서 4개의 간격만큼 값을 빼줌
let width = UIScreen.main.bounds.width - (spacing * 4)
// 전체 폭을 3으로 나눈 값만큼 폭을 설정해주고 이에 비례하여 높이도 설정해줌
layout.itemSize = CGSize(width: width / 3, height: width / 3 * 1.2)

minimumLineSpacing

행과 행 사이의 최소 간격을 설정해줌

layout.minimumLineSpacing = spacing

minimumInteritemSpacing

열과 열 사이의 최소 간격을 설정해줌

layout.minimumInteritemSpacing = spacing

scrollDirection

스크롤 방향을 가로 혹은 세로로 설정해줄 수 있음

layout.scrollDirection = .vertical

sectionInset

콘텐츠 영역 내부의 margin 값을 설정해줄 수 있음 (해당 부분도 스크롤 가능 영역으로 인식됨)

layout.sectionInset = UIEdgeInsets(top: spacing, left: spacing, bottom: spacing, right: spacing)

Layout 적용

mainCollectionView.collectionViewLayout = layout

Tag - AddTarget & ReloadRows

  • 현재 viewController 내에는 false값을 100개 가진 mainArray 배열이 있다.

  • 하트 버튼을 클릭할 때마다 채워진 하트와 빈 하트가 번갈아가면서 보이도록 구현하고자 한다.

  • 먼저 배열을 선언해준다.

var mainArray = Array(repeating: false, count: 100)
  • cellForItemAt 메서드에서 각 Cell 안에 있는 버튼에 indexPath값을 활용하여 tag를 달아줄 수 있다. 이를 통해 배열의 각 index에 있는 값과 버튼들을 일치시켜줄 수 있다.
let item = mainArray[indexPath.item]
let image = item == true ? UIImage(systemName: "heart.fill") : UIImage(systemName: "heart")
cell.heartButton.setImage(image, for: .normal)
cell.mainImageView.backgroundColor = .red
cell.heartButton.tag = indexPath.item
  • 여기서 더 나아가 클릭할 때 마다 이미지를 변경할 수 있도록 메서드를 추가해줘야한다. 먼저 버튼에 addTarget을 해준다.
cell.heartButton.addTarget(self, action: #selector(heartButtonTapped(selectButton:)), for: .touchUpInside)
  • selector는 Objective-C를 인식시키기 위해서 앞에 @objc를 붙여줘야한다.
    클릭할 때마다 해당 버튼이 가지고 있는 tag값을 이용하여 배열에서 해당 index의 값을 현재의 반대값으로 업데이트해준다.
  • 그리고 업데이트된 값을 view에 적용시키기 위하여 reload를 해준다. 이때 reloadData()를 해도 되지만 특정한 위치의 값만 update시키면 된다면 reloadItems(at:)을 활용해준다. tableView에서는 동일한 기능의 메서드가 reloadRows로 정의돼있다.
@objc func heartButtonTapped(selectButton: UIButton) {
        mainArray[selectButton.tag] = !mainArray[selectButton.tag]
        mainCollectionView.reloadItems(at: [IndexPath(item: selectButton.tag, section: 0)])
    }

👩‍💻 Mission

Core Location

Meet the Location Button(WWDC21)
What's new in location(WWDC20)
What's New in Core Location(WWDC15)

좋은 웹페이지 즐겨찾기