Computer >> Máy Tính >  >> Điện thoại thông minh >> iPhone

Cách lập trình tạo bản sao Spotify cho iOS bằng Tự động thanh toán:thêm ảnh và cập nhật giao diện người dùng

Đây là phần thứ hai của bài viết về cách tạo bản sao giao diện người dùng Spotify với tính năng Tự động thanh toán theo chương trình. Nếu bạn bỏ lỡ phần đầu tiên, đừng lo lắng - chỉ cần đi và kiểm tra nó ngay bây giờ.

Trong bài viết này, chúng tôi sẽ thêm một số hình ảnh chế nhạo và cố gắng làm cho giao diện người dùng giống như của Spotify.

Đây là những gì chúng ta sẽ làm hôm nay?

Cách lập trình tạo bản sao Spotify cho iOS bằng Tự động thanh toán:thêm ảnh và cập nhật giao diện người dùng

Đây là những gì chúng ta đã bỏ qua trong phần đầu tiên:

Cách lập trình tạo bản sao Spotify cho iOS bằng Tự động thanh toán:thêm ảnh và cập nhật giao diện người dùng

Bước tiếp theo là tạo các ô tùy chỉnh. Vì vậy, hãy bắt đầu bằng cách tạo một cái với tên SubCustomCell .

Đầu tiên, tạo một tệp Swift mới bên trong thư mục dự án và đặt tên là SubCustomCell.swift . Tệp này sẽ chứa ô tùy chỉnh của chúng tôi sẽ đại diện cho Danh sách phát. Sau khi tạo tệp, hãy thử thêm mã bên dưới và khởi tạo ô, có thể bằng backgroundColor , để xem những thay đổi về giao diện người dùng khi chúng tôi đăng ký ô với collectionView .

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")
    }
}

Sau đó, chúng tôi đăng ký SubCustomCell bên trong CustomCell.swift trong init khối. Thay thế UICollectionViewCell.self với SubCustomCell như bên dưới.

 collectionView.register(SubCustomCell.self, forCellWithReuseIdentifier: cellId)

Ngoài ra, chúng tôi cần thực hiện sửa đổi trên cellForItemAt và làm cho nó phù hợp với SubCustomCell như sau.

 func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! SubCustomCell
        // cell.backgroundColor = .yellow
        
        return cell
    }

Bạn sẽ thấy backgroundColor đã thay đổi thành red .

Cách lập trình tạo bản sao Spotify cho iOS bằng Tự động thanh toán:thêm ảnh và cập nhật giao diện người dùng
Swift CustomCell

Cho đến thời điểm này, mọi thứ nên đơn giản và rõ ràng.

Bây giờ chúng ta sẽ điền vào các ô bằng một số hình ảnh chế nhạo và tạo một ImageView bên trong mỗi ô. Tôi đã tải xuống một số hình ảnh ngẫu nhiên từ pexels.com, nhưng hãy thoải mái sử dụng bất kỳ hình ảnh nào bạn thích (bao gồm cả những hình ảnh này). Bạn có thể tìm thấy chúng trong tệp dự án trên Github.

Hãy tạo UIImageView bên trong SubCustomCell.swift và thực hiện một số ràng buộc.

    let ImageView : UIImageView = {
       let iv = UIImageView()
        iv.backgroundColor = .yellow
        return iv
        
    }()

Và thêm nó vào view trong init chặn sử dụng addSubView .

 override init(frame: CGRect) {
        super.init(frame: frame)
        addSubview(ImageView)
            
    }

Bây giờ hãy tạo ImageView chiếm tất cả không gian trong ô với các ràng buộc bên dưới.

 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 đại diện cho neo bên trái của ô
  • rightAnchor đại diện cho neo bên phải của ô
  • bottomAnchor đại diện cho neo dưới cùng của ô
  • topAnchor đại diện cho điểm neo trên cùng của ô

Và bằng cách tạo ImageView anchor trên cùng của ô bằng với anchor trên cùng của ô (và làm tương tự cho ImageView neo trái, phải và dưới) nó tạo thành ImageView chiếm tất cả không gian của SubCustomCell (ô).

Lưu ý:trước tiên bạn cần sử dụng translatesAutoresizingMaskIntoConstraints để có thể áp dụng các ràng buộc cho các phần tử. Cũng đừng quên gọi isActive và gán nó cho true - nếu không làm điều đó, các ràng buộc sẽ không hoạt động và không có gì thay đổi.

ImageView nên có một hình ảnh, vì vậy hãy thêm một hình ảnh.

 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
        
    }()

Và nếu bạn xây dựng và chạy ứng dụng, bạn sẽ thấy kết quả và hình ảnh mà chúng tôi đã thêm vào SubCustomCell .

Cách lập trình tạo bản sao Spotify cho iOS bằng Tự động thanh toán:thêm ảnh và cập nhật giao diện người dùng

Mát mẻ ?. Bây giờ có một phần tử chúng ta nên thêm vào SubCustomCell để kết thúc. Chúng tôi cần một tiêu đề đại diện cho tiêu đề của danh sách phát:UILabel .

Đối với tiêu đề, nó sẽ như thế này:

 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
    }()

Tôi chỉ đặt một số văn bản ngẫu nhiên ở đó - bạn có thể đặt bất cứ thứ gì bạn thích. Bước tiếp theo là thêm phần tử vào dạng xem và cung cấp cho nó một số ràng buộc. Tiêu đề sẽ được đặt ở cuối ImageView .

Thêm vào chế độ xem:

addSubview(TitleLabel)

Áp dụng các ràng buộc cho cả ImageViewTitleLabel

 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

Và chúng ta bắt đầu!

Cách lập trình tạo bản sao Spotify cho iOS bằng Tự động thanh toán:thêm ảnh và cập nhật giao diện người dùng

Chúng tôi đã làm cho hình ảnh chiếm hầu hết không gian trong ô và phần còn lại được chiếm bởi tiêu đề. Như bạn có thể thấy, bạn có thể cuộn theo chiều ngang trong từng phần và cũng có thể cuộn theo chiều dọc trong toàn bộ màn hình.

Cách lập trình tạo bản sao Spotify cho iOS bằng Tự động thanh toán:thêm ảnh và cập nhật giao diện người dùng

Bây giờ chúng ta đưa một số dữ liệu giả vào các ô để làm cho nó giống như thật. Để làm điều đó, tôi đã tạo một JSON tệp chứa một số dữ liệu ngẫu nhiên cho các phần và danh sách phát.

Đầu tiên, hãy tạo hai cấu trúc, SectionPlaylist . Chúng tôi tạo một tệp riêng cho mỗi cấu trúc.

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 ?? ""
    }
   
}

Và sau đó bên trong ViewController.swift chúng tôi tạo một hàm tìm nạp JSON cho chúng tôi và lưu trữ kết quả trong một mảng.


        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 hàm được gọi trong ViewDidLoad phương pháp. Chúng tôi cũng có một biến được gọi là sections nơi chúng tôi lưu trữ kết quả:

 var sections = [Section]()

Bước tiếp theo là chuyển dữ liệu từ ViewController thành CustomCell . Để làm được điều đó, chúng tôi tạo một biến bên trong CustomCell sẽ nhận dữ liệu cho từng phần:

 var section : Section?{
        didSet{
            print("section ✅",self.section)
        }
    }

Chúng tôi sử dụng cellForItemAt bên trong ViewController phương pháp chuyển dữ liệu trực tiếp đến 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
    }

Lưu ý:chúng tôi luôn gọi là self .collectionView.reloadData() mọi lúc fetchJson được gọi như vậy khối bên dưới, bên trong CustomCell , cũng sẽ được gọi. Kiểm tra bảng điều khiển, shift + lệnh + C:

 var section : Section? {
        didSet{
            print("section ✅",self.section)
        }
    }

Điều đầu tiên chúng tôi thay đổi là đặt tiêu đề phần:

 var section : Section? {
        didSet{
            print("section ✅",self.section)
            guard let section = self.section else {return}
            self.titleLabel.text = section.title
        }
    }

Và sau đó bạn sẽ thấy rằng mỗi phần có một tiêu đề cụ thể trên màn hình?.

Cách lập trình tạo bản sao Spotify cho iOS bằng Tự động thanh toán:thêm ảnh và cập nhật giao diện người dùng

Bây giờ là lúc chuyển dữ liệu xuống SubCustomCell . Chúng tôi làm tương tự như chúng tôi đã làm ở trên. Chúng ta cần chuyển playlists mảng, vì vậy chúng tôi tạo một biến có tên playlists bên trong CustomCell .

 var playlists : [PlayList]() //empty 

Đầu tiên, chúng tôi ánh xạ qua playlists từ JSON . Sau đó, chúng tôi thêm từng danh sách phát với playlists var.

 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()
        }
    }

Chú ý! Nếu bạn cố gắng chạy ứng dụng, nó có thể bị lỗi. Điều này là do chúng tôi đã quên đặt số phần. Vì chúng tôi hiện đang nhận dữ liệu từ JSON, nên số lượng phải động dựa trên số phần chúng tôi có. Số phần phải bằng số phần bên trong JSON , vì vậy chúng tôi cần sửa đổi numberOfItemsInSection bên trong ViewController bên dưới:

   override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return sections.count
    }

Chúng tôi làm điều tương tự với cùng một phương pháp bên trong CustomCell.swift - nhưng ở đây chúng tôi xem xét số của playlists thay vào đó.

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return  self.playlists.count
    }

Bước cuối cùng chúng ta phải hoàn thành là chuyển từng danh sách phát duy nhất Object thành SubCustomCell trong cellForItemAt trong 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
    }

Và chúng tôi sẽ lấy dữ liệu đó bên trong SubCustomCell qua playlist và cuối cùng là hiển thị tiêu đề và hình ảnh của danh sách phát.

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
               
           }
       }

Tôi nghĩ bây giờ mọi thứ sẽ hoạt động tốt, giống như bên dưới?

Cách lập trình tạo bản sao Spotify cho iOS bằng Tự động thanh toán:thêm ảnh và cập nhật giao diện người dùng

Một bản cập nhật cuối cùng cho giao diện người dùng:chúng tôi phải thêm một số phần đệm và lề vào sectionplaylist tiêu đề và thu nhỏ danh sách phát một chút.

Đầu tiên chúng ta hãy thêm một số đệm cho tiêu đề phần. Để làm điều đó, chúng tôi chỉ cần cung cấp constant thuộc tính một số giá trị số bên trong ô phần CustomCell và trong setupSubCells :

 collectionView.topAnchor.constraint(equalTo: titleLabel.bottomAnchor,constant: 15).isActive = true

Và nếu bạn thấy toàn bộ collectionView đến ở cuối titleLabel , tất cả những gì chúng ta cần làm là thêm nhiều dung lượng hơn bằng cách thêm 15 :

Cách lập trình tạo bản sao Spotify cho iOS bằng Tự động thanh toán:thêm ảnh và cập nhật giao diện người dùng

Tiếp theo, chúng ta đến với tiêu đề của playlist . Điều này sẽ nằm bên trong SubCustomCell và chúng tôi chỉ cần thêm không gian ở cuối ImageView.

 ImageView.bottomAnchor.constraint(equalTo: TitleLabel.topAnchor,constant: -15).isActive = true

Chúng tôi đã có hằng số ở đó. Để nó hoạt động, giá trị phải là -15

Cách lập trình tạo bản sao Spotify cho iOS bằng Tự động thanh toán:thêm ảnh và cập nhật giao diện người dùng

Cuối cùng, danh sách phát cần phải nhỏ hơn một chút. Điều này thật dễ dàng:chúng tôi chỉ tạo playlist chiều cao và chiều rộng của ô bằng section chiều cao của ô chia cho 2, giống như bên dưới:

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)
        
    }

Đặt chiều cao của ImageView bằng 150 nữa.

  //SubCutomCell.swift
  ImageView.heightAnchor.constraint(equalToConstant: 150).isActive = true

Và chúng ta bắt đầu?.

Cách lập trình tạo bản sao Spotify cho iOS bằng Tự động thanh toán:thêm ảnh và cập nhật giao diện người dùng

Hoàn hảo! Tôi nghĩ như vậy là đủ cho ngày hôm nay - tôi không muốn làm bài viết này quá dài. Vì vậy, chúng ta sẽ có một phần khác, nơi chúng ta sẽ thêm TabBar và mô tả, cũng như một số biểu tượng cho danh sách phát.

Xem Mã nguồn đầy đủ trên GitHub ?.

Cảm ơn vì đã dành thời gian cho tôi. Tôi hy vọng tôi đã không bỏ lỡ bất cứ điều gì. Nếu tôi đã làm, vui lòng @mention tôi trên Twitter, hoặc nếu bạn có bất kỳ câu hỏi nào hoặc bổ sung cho bài đăng này, cánh cửa luôn mở cho bất kỳ ai. Cảm ơn ??.

Đăng ký vào danh sách email của tôi để được thông báo khi phần thứ ba của hướng dẫn này được xuất bản.

Nhân tiện, gần đây tôi đã làm việc với một nhóm kỹ sư phần mềm mạnh mẽ cho một trong những ứng dụng di động của tôi. Tổ chức thật tuyệt vời và sản phẩm được phân phối rất nhanh, nhanh hơn nhiều so với các công ty và dịch giả tự do khác mà tôi đã làm việc cùng và tôi nghĩ rằng tôi có thể thành thật giới thiệu họ cho các dự án khác ngoài đó. Gửi email cho tôi nếu bạn muốn liên hệ - [email protected].