이것은 프로그래밍 방식으로 autoLayout을 사용하여 Spotify UI 복제본을 구축하는 방법에 대한 기사의 두 번째 부분입니다. 첫 번째 부분을 놓쳤더라도 걱정하지 마세요. 지금 바로 가서 확인하세요.
이 기사에서는 조롱된 사진을 추가하고 UI가 Spotify와 동일하게 보이도록 하려고 합니다.
이것이 오늘 우리가 할 일입니까?
이것은 첫 번째 부분에서 생략된 것입니다:
다음 단계는 맞춤형 셀을 만드는 것입니다. 먼저 SubCustomCell
이라는 이름으로 생성해 보겠습니다. .
먼저 프로젝트 폴더 안에 새 Swift 파일을 만들고 이름을 SubCustomCell.swift
으로 지정합니다. . 이 파일에는 재생 목록을 나타내는 사용자 지정 셀이 포함됩니다. 파일을 만든 후 아래 코드를 추가하고 backgroundColor
로 셀을 초기화해 보세요. , collectionView
로 셀을 등록할 때 UI 변경 사항을 보려면 .
import UIKit
class SubCustomCell: UICollectionViewCell {
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = .red
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
그런 다음 SubCustomCell
를 등록합니다. CustomCell.swift
내부 init
내 차단하다. UICollectionViewCell.self
바꾸기
아래와 같이SubCustomCell
포함
collectionView.register(SubCustomCell.self, forCellWithReuseIdentifier: cellId)
또한 cellForItemAt
를 수정해야 합니다. 메소드를 만들고 SubCustomCell
를 준수하도록 합니다. 다음과 같습니다.
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! SubCustomCell
// cell.backgroundColor = .yellow
return cell
}
backgroundColor
이 표시되어야 합니다. red
로 변경됨 .
여기까지는 모든 것이 간단하고 명확해야 합니다.
이제 모의 그림으로 셀을 채우고 ImageView
각 셀 내부. 이미 pexels.com에서 임의의 사진을 다운로드했지만 원하는 사진(이 사진 포함)을 자유롭게 사용할 수 있습니다. Github의 프로젝트 파일에서 찾을 수 있습니다.
UIImageView
를 만들어 봅시다. SubCustomCell.swift
내부 그리고 약간의 제약을 가하십시오.
let ImageView : UIImageView = {
let iv = UIImageView()
iv.backgroundColor = .yellow
return iv
}()
view
에 추가합니다. init
내 addSubView
를 사용하여 차단 .
override init(frame: CGRect) {
super.init(frame: frame)
addSubview(ImageView)
}
이제 ImageView
를 만들어 보겠습니다. 아래의 제약 조건으로 셀 내의 모든 공간을 차지합니다.
ImageView.translatesAutoresizingMaskIntoConstraints = false
ImageView.topAnchor.constraint(equalTo: topAnchor).isActive = true
ImageView.leftAnchor.constraint(equalTo: leftAnchor).isActive = true
ImageView.rightAnchor.constraint(equalTo: rightAnchor).isActive = true
ImageView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
LeftAnchor
셀의 왼쪽 앵커를 나타냅니다.rightAnchor
셀의 오른쪽 앵커를 나타냅니다.bottomAnchor
셀의 하단 앵커를 나타냅니다.topAnchor
셀의 상단 앵커를 나타냅니다.
그리고 ImageView
를 만들어서 의 상단 앵커는 셀의 상단 앵커와 동일합니다(ImageView
에 대해서도 동일). 의 왼쪽, 오른쪽 및 아래쪽 앵커)는 ImageView
SubCustomCell
의 모든 공간을 차지합니다. (셀).
참고:먼저 translatesAutoresizingMaskIntoConstraints
을 사용해야 합니다. 요소에 제약 조건을 적용할 수 있습니다. 또한 isActive
로 전화하는 것을 잊지 마십시오. 속성을 지정하고 true
에 할당합니다. – 그렇게 하지 않으면 제약 조건이 작동하지 않으며 아무 것도 변경되지 않습니다.
ImageView
이미지가 있어야 하므로 이미지를 추가해 보겠습니다.
let ImageView : UIImageView = {
let iv = UIImageView()
iv.backgroundColor = .yellow
// we have >image1< file inside the project
iv.image = UIImage(named: "image1")
iv.contentMode = .scaleAspectFill
iv.clipsToBounds = true
return iv
}()
앱을 빌드하고 실행하면 SubCustomCell
에 추가한 결과와 그림이 표시됩니다. .
시원한 ?. 이제 SubCustomCell
에 추가해야 하는 요소가 있습니다. 끝내기 위해. 재생 목록의 제목을 나타내는 제목이 필요합니다. UILabel
.
제목은 다음과 같습니다.
let TitleLabel : UILabel = {
let lb = UILabel()
lb.textColor = UIColor.lightGray
lb.font = UIFont.systemFont(ofSize: 16)
lb.font = UIFont.boldSystemFont(ofSize: 20)
lb.text = "Evening Music"
return lb
}()
나는 거기에 임의의 텍스트를 넣었습니다. 원하는 것을 넣을 수 있습니다. 다음 단계는 뷰에 요소를 추가하고 몇 가지 제약 조건을 부여하는 것입니다. 제목은 ImageView
하단에 배치됩니다. .
보기에 추가:
addSubview(TitleLabel)
ImageView
에 제약 조건 적용 및 TitleLabel
ImageView.translatesAutoresizingMaskIntoConstraints = false
ImageView.topAnchor.constraint(equalTo: topAnchor).isActive = true
ImageView.leftAnchor.constraint(equalTo: leftAnchor).isActive = true
ImageView.rightAnchor.constraint(equalTo: rightAnchor).isActive = true
ImageView.heightAnchor.constraint(equalToConstant: 240).isActive = true
ImageView.bottomAnchor.constraint(equalTo: TitleLabel.topAnchor).isActive = true
TitleLabel.translatesAutoresizingMaskIntoConstraints = false
TitleLabel.topAnchor.constraint(equalTo: ImageView.bottomAnchor,constant: 10).isActive = true
TitleLabel.leftAnchor.constraint(equalTo: leftAnchor, constant: 5).isActive = true
TitleLabel.rightAnchor.constraint(equalTo: rightAnchor, constant: -5).isActive = true
이제 시작하겠습니다!
우리는 그림이 셀의 대부분의 공간을 차지하도록 만들고 나머지는 제목으로 차지합니다. 보시다시피 각 섹션에서 가로로 스크롤할 수 있으며 전체 화면에서 세로로도 스크롤할 수 있습니다.
이제 실제처럼 느껴지도록 모의 데이터를 셀에 넣습니다. 이를 위해 JSON
을 만들었습니다. 섹션 및 재생 목록에 대한 임의의 데이터가 포함된 파일입니다.
먼저 두 개의 구조체 Section
를 생성해 보겠습니다. 및 Playlist
. 각 구조체에 대해 별도의 파일을 만듭니다.
section.swift
import Foundation
struct Section {
var title : String
var playlists : NSArray
init(dictionary:[String : Any]) {
self.title = dictionary["title"] as? String ?? ""
self.playlists = dictionary["playlists"] as? NSArray ?? []
}
}
playlist.swift
//
// playlist.swift
// spotifyAutoLayout
//
// Created by admin on 12/6/19.
// Copyright © 2019 Said Hayani. All rights reserved.
//
import Foundation
struct PlayList {
var title: String
var image : String
init(dictionary : [String : Any]) {
self.title = dictionary["title"] as? String ?? ""
self.image = dictionary["image"] as? String ?? ""
}
}
그런 다음 ViewController.swift
내부 JSON을 가져오고 결과를 배열에 저장하는 함수를 만듭니다.
print("attempt to fetch Json")
if let path = Bundle.main.path(forResource: "test", ofType: "json") {
do {
let data = try Data(contentsOf: URL(fileURLWithPath: path), options: .mappedIfSafe)
let jsonResult = try JSONSerialization.jsonObject(with: data, options: .mutableLeaves)
if let jsonResult = jsonResult as? [ Any] {
// do stuff
jsonResult.forEach { (item) in
let section = Section(dictionary: item as! [String : Any])
// print("FEtching",section.playlists)
self.sections.append(section)
}
self.collectionView.reloadData()
}
} catch {
// handle error
}
}
}
fetchJson
함수는 ViewDidLoad
내에서 호출됩니다. 방법. sections
라는 변수도 있습니다. 결과를 저장하는 위치:
var sections = [Section]()
다음 단계는 ViewController
의 데이터를 전달하는 것입니다. CustomCell
로 . 이를 위해 CustomCell
안에 변수를 만듭니다. 각 섹션에 대한 데이터 수신:
var section : Section?{
didSet{
print("section ✅",self.section)
}
}
cellForItemAt
를 사용합니다. ViewController
내부 데이터를 CustomCell
에 직접 전달하는 메소드 .
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! CustomCell
cell.section = sections[indexPath.item]
return cell
}
참고:우리는 항상 self
을 호출합니다. .collectionView.reloadData()
매번 fetchJson
CustomCell
내부에서 아래 블록이 호출됩니다. , 도 호출됩니다. 콘솔 확인, shift
+ 명령 + C:
var section : Section? {
didSet{
print("section ✅",self.section)
}
}
가장 먼저 변경한 것은 섹션 제목을 설정하는 것입니다.
var section : Section? {
didSet{
print("section ✅",self.section)
guard let section = self.section else {return}
self.titleLabel.text = section.title
}
}
그러면 화면에 각 섹션에 특정 제목이 있는 것을 볼 수 있습니까?
이제 데이터를 SubCustomCell
으로 전달할 차례입니다. . 우리는 위에서 했던 것과 같은 일을 합니다. playlists
을 전달해야 합니다. 배열이므로 playlists
이라는 변수를 만듭니다. CustomCell
내부 .
var playlists : [PlayList]() //empty
먼저 playlists
를 통해 매핑합니다. JSON
에서 . 그런 다음 playlists
을 사용하여 각 재생 목록을 추가합니다. 변수
var section : Section? {
didSet{
print("section ✅",self.section)
guard let section = self.section else {return}
self.titleLabel.text = section.title
// append to playlists array
self.section?.playlists.forEach({ (item) in
let playlist = PlayList(dictionary: item as! [String : Any])
self.playlists.append(playlist)
})
self.collectionView.reloadData()
}
}
주목! 앱을 실행하려고 하면 충돌할 수 있습니다. 섹션 수를 설정하는 것을 잊어버렸기 때문입니다. 이제 JSON에서 데이터를 수신하기 때문에 섹션 수에 따라 숫자가 동적이어야 합니다. 섹션 수는 JSON
안의 섹션 수와 같아야 합니다. , 그래서 numberOfItemsInSection
를 수정해야 합니다. ViewController
내부 아래로 :
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return sections.count
}
CustomCell.swift
내에서 동일한 방법으로 동일한 작업을 수행합니다. – 하지만 여기서 playlists
대신.
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return self.playlists.count
}
완료해야 하는 마지막 단계는 각 단일 재생 목록 Object
을 전달하는 것입니다. SubCustomCell
로 cellForItemAt
이내 CustomCell.swift
에서 .
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! SubCustomCell
// here ?
cell.playlist = playlists[indexPath.item]
return cell
}
그리고 우리는 SubCustomCell
안에 있는 데이터를 얻을 것입니다. playlist
을 통해 변수를 만들고 마지막으로 재생 목록의 제목과 이미지를 표시합니다.
var playlist : PlayList? {
didSet{
print("Playlist ?",self.playlist)
guard let playlist = self.playlist else {return}
// The Image ?
self.ImageView.image = UIImage(named: playlist.image)
// the playlist title ?
self.TitleLabel.text = self.playlist?.title
}
}
이제 아래와 같이 모든 것이 잘 작동해야 한다고 생각합니까?
UI에 대한 마지막 업데이트:section
에 패딩과 여백을 추가해야 합니다. 및 playlist
제목을 지정하고 재생 목록을 조금 더 작게 만드세요.
먼저 섹션 제목에 패딩을 추가해 보겠습니다. 그렇게 하려면 constant
섹션 셀 CustomCell
내의 일부 숫자 값 속성 및 setupSubCells
내 :
collectionView.topAnchor.constraint(equalTo: titleLabel.bottomAnchor,constant: 15).isActive = true
전체 collectionView
가 표시되면 titleLabel
하단에 입력하세요. , 15
을 추가하여 더 많은 공간을 추가하기만 하면 됩니다. :
다음으로 playlist
의 제목이 나옵니다. . 이것은 SubCustomCell
안에 있을 것입니다. , ImageView 하단에 공간을 더 추가하기만 하면 됩니다.
ImageView.bottomAnchor.constraint(equalTo: TitleLabel.topAnchor,constant: -15).isActive = true
우리는 이미 거기에 상수를 가지고 있습니다. 작동하려면 값이 -15
여야 합니다.
마지막으로 재생 목록은 조금 더 작아야 합니다. 이것은 쉽습니다. playlist
section
와 같은 셀의 높이와 너비 아래와 같이 셀 높이를 2로 나눈 값:
CustomCell.swift
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let width = frame.height / 2
let height = frame.height / 2
return CGSize(width: width, height: height)
}
ImageView의 높이를 150
과 같게 만듭니다. 뿐만 아니라.
//SubCutomCell.swift
ImageView.heightAnchor.constraint(equalToConstant: 150).isActive = true
이제 시작하겠습니다.
완벽한! 오늘은 그것으로 충분하다고 생각합니다. 이 기사를 너무 길게 만들고 싶지 않습니다. 따라서 TabBar
을 추가할 또 다른 부분이 있습니다. 및 설명 및 재생 목록의 일부 아이콘.
보기 GitHub의 전체 소스 코드 ?.
시간 내 줘서 고마워. 아무것도 놓치지 않았으면 좋겠습니다. 내가 한 경우 Twitter에서 나를 @멘션하거나 질문이 있거나 이 게시물에 추가할 사항이 있는 경우 문은 항상 누구에게나 열려 있습니다. 감사합니다??.
구독 이 튜토리얼의 세 번째 파트가 게시될 때 알림을 받으려면 내 이메일 목록에.
그런데, 저는 최근에 제 모바일 애플리케이션 중 하나를 위해 강력한 소프트웨어 엔지니어 그룹과 함께 일했습니다. 조직은 훌륭했고 제품은 내가 함께 일한 다른 회사 및 프리랜서보다 훨씬 빠르고 매우 빠르게 전달되었으며 다른 프로젝트에 대해 정직하게 추천할 수 있다고 생각합니다. 연락을 원하시면 저에게 이메일을 보내주세요 — [email protected].