#
을 붙이면 된다.var notice = #"온라인 라이브 수업은 "Zoom"으로 진행합니다."#
➡️ 온라인 라이브 수업은 "Zoom"으로 진행합니다.
var notice = #"온라인 라이브 수업은 \Zoom\으로 진행합니다."#
➡️ 온라인 라이브 수업은 \Zoom\으로 진행합니다.
\
과 문자 사이에 #
을 추가해주면 된다.var notice = #"온라인 라이브 수업은 \#n\Zoom\으로 진행합니다."#
➡️ 온라인 라이브 수업은
\Zoom\으로 진행합니다.
#
을 추가해줘야 한다.var onlineService = "WhaleOn"
var notice = #"온라인 라이브 수업은 \#(onlineService)으로 진행합니다."#
➡️ 온라인 라이브 수업은 WhaleOn으로 진행합니다.
WebKit View
를 사용하면 된다.delegate
연결을 해줘야한다!searchBarSearchButtonClicked
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)
}
앱이 서버에 전송하는 데이터에 대한 보안 설정
HTTP 프로토콜을 사용하는 외부 서버와 통신하기 위해 설정
HTTPS(security): 데이터 패킷을 암호화여 전송하기 때문에 보안상 안정
모든 도메인에 대한 HTTP 통신 허용: 보안상 권장되지 않는 방식
@IBOutlet var tagCollectionView: UICollectionView!
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 10
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
// 이 코드 대신 tag 설정해두고 사용해도됨
return collectionView == tagCollectionView ? 10 : mainArray.count
}
row
가 item
으로 변경된 것 외에는 코드 구성이 거의 동일하다.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
}
tagCollectionView.delegate = self
tagCollectionView.dataSource = self
let secondNibName = UINib(nibName: TagCollectionViewCell.identifier, bundle: nil)
tagCollectionView.register(secondNibName, forCellWithReuseIdentifier: TagCollectionViewCell.identifier)
상하좌우 여백(수직 섹션) + 셀과 셀 사이의 간격 + 셀 상하
let layout = UICollectionViewFlowLayout()
// 각 셀과 셀 사이의 간격 설정
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)
행과 행 사이의 최소 간격을 설정해줌
layout.minimumLineSpacing = spacing
열과 열 사이의 최소 간격을 설정해줌
layout.minimumInteritemSpacing = spacing
스크롤 방향을 가로 혹은 세로로 설정해줄 수 있음
layout.scrollDirection = .vertical
콘텐츠 영역 내부의 margin 값을 설정해줄 수 있음 (해당 부분도 스크롤 가능 영역으로 인식됨)
layout.sectionInset = UIEdgeInsets(top: spacing, left: spacing, bottom: spacing, right: spacing)
mainCollectionView.collectionViewLayout = layout
현재 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
cell.heartButton.addTarget(self, action: #selector(heartButtonTapped(selectButton:)), for: .touchUpInside)
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)])
}
Meet the Location Button(WWDC21)
What's new in location(WWDC20)
What's New in Core Location(WWDC15)