এটি প্রোগ্রাম্যাটিকভাবে অটোলেআউট সহ একটি স্পটিফাই UI ক্লোন তৈরি করার নিবন্ধের দ্বিতীয় অংশ। আপনি যদি প্রথম অংশ মিস করেন, কোন উদ্বেগ নেই - অনুগ্রহ করে এখনই যান এবং এটি পরীক্ষা করুন।
এই নিবন্ধে, আমরা কিছু উপহাস করা ছবি যোগ করতে যাচ্ছি এবং UI কে Spotify-এর মতো দেখতে চেষ্টা করব৷
এই আমরা আজ কি করতে যাচ্ছি?
আমরা প্রথম অংশে এটি ছেড়ে দিয়েছিলাম:
পরবর্তী ধাপ হল কাস্টমাইজড সেল তৈরি করা। তাহলে চলুন শুরু করা যাক SubCustomCell নামের একটি তৈরি করে .
প্রথমে, প্রোজেক্ট ফোল্ডারের ভিতরে একটি নতুন সুইফট ফাইল তৈরি করুন এবং সেটির নাম দিন 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 + কমান্ড + সি:
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.
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-এ সম্পূর্ণ উৎস কোড ?.
আপনার সময় জন্য ধন্যবাদ. আমি আশা করি আমি কিছু মিস করিনি। যদি আমি টুইটারে আমাকে @উল্লেখ করে থাকি, অথবা যদি আপনার কোন প্রশ্ন থাকে বা এই পোস্টে একটি সংযোজন থাকে তবে দরজা সবসময় যে কারো জন্য খোলা থাকে। ধন্যবাদ??.
সাবস্ক্রাইব করুন এই টিউটোরিয়ালের তৃতীয় অংশ প্রকাশিত হলে আমার ইমেল তালিকায় অবহিত করা হবে।
প্রসঙ্গক্রমে, আমি সম্প্রতি আমার একটি মোবাইল অ্যাপ্লিকেশনের জন্য সফ্টওয়্যার ইঞ্জিনিয়ারদের একটি শক্তিশালী গ্রুপের সাথে কাজ করেছি। সংস্থাটি দুর্দান্ত ছিল, এবং পণ্যটি খুব দ্রুত বিতরণ করা হয়েছিল, আমি যে অন্যান্য ফার্ম এবং ফ্রিল্যান্সারদের সাথে কাজ করেছি তার চেয়ে অনেক দ্রুত, এবং আমি মনে করি আমি সততার সাথে তাদের অন্যান্য প্রকল্পগুলির জন্য সুপারিশ করতে পারি। আপনি যদি যোগাযোগ করতে চান তাহলে আমাকে একটি ইমেল পাঠান।