아래와 같이 tableview와 cell을 만들어준다. 그리고 delegate과 datasource를 연결해준다.
아래와 같이 tableview를 설정해준다.
import UIKit
class CustomCellViewController: UIViewController {
let list = WorldTime.generateData()
override func viewDidLoad() {
super.viewDidLoad()
}
}
extension CustomCellViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return list.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
let target = list[indexPath.row]
cell.textLabel?.text = target.location
cell.detailTextLabel?.text = "\(target.date) \(target.time)"
return cell
}
}
import Foundation
struct WorldTime {
let date: String
let hoursFromGMT: Int
let location: String
let ampm: String
let time: String
static func generateData() -> [WorldTime] {
let list = [("Asia/Seoul", "서울"), ("America/New_York", "뉴욕"), ("Europe/Paris", "파리"), ("Europe/London", "런던"), ("Europe/Zurich", "취리히")]
let now = Date()
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "Ko_kr")
formatter.doesRelativeDateFormatting = true
var result = [WorldTime]()
for (timeZone, location) in list {
guard let tz = TimeZone(identifier: timeZone) else { continue }
let dt = now.addingTimeInterval(TimeInterval(tz.secondsFromGMT() - (9 * 3600)))
formatter.dateStyle = .short
formatter.timeStyle = .none
let date = formatter.string(from: dt)
formatter.dateFormat = "a"
let ampm = formatter.string(from: dt)
formatter.dateFormat = "h:mm"
let time = formatter.string(from: dt)
let hoursFromGMT = (tz.secondsFromGMT() / 3600) - 9
let data = WorldTime(date: date, hoursFromGMT: hoursFromGMT, location: location, ampm: ampm, time: time)
result.append(data)
}
return result
}
}
tableview 한개의 cell의 height를 설정해줄 수 있다.
새로운 cell을 추가해주고(customCell로 identifier를 설정해준다), 새로운 Cell에 stackview 두 개를 넣어준다.
그리고 새로운 cell에 있는 각각의 label에 tag를 100,200,300,400으로 설정해준다.
그리고 원래 viewcontroller의 datasource를 아래와 같이 설정할 수 있다.
extension CustomCellViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return list.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "customCell", for: indexPath)
let target = list[indexPath.row]
if let dataLabel = cell.viewWithTag(100) as? UILabel{
dataLabel.text = "\(target.date), \(target.hoursFromGMT)시간"
}
if let locationLabel = cell.viewWithTag(200) as? UILabel{
locationLabel.text = target.location
}
if let ampmLabel = cell.viewWithTag(300) as? UILabel{
ampmLabel.text = target.ampm
}
if let timeLabel = cell.viewWithTag(400) as? UILabel{
timeLabel.text = target.time
}
return cell
}
}
CocoaTouch로 새로운 tableviewcell(TImeTableViewCell)을 만들어준다.
그리고 새로운 cell에 Class timetableviewcell을 넣어준다.
그리고 TImeTableViewCell에 label들의 Outlet을 설정해준다.
import UIKit
class TImeTableViewCell: UITableViewCell {
@IBOutlet weak var timeLabel: UILabel!
@IBOutlet weak var ampmLabel: UILabel!
@IBOutlet weak var locationLabel: UILabel!
@IBOutlet weak var dateLabel: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
extension CustomCellViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return list.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// DownCasting을 해줘야된다.
let cell = tableView.dequeueReusableCell(withIdentifier: "customCell", for: indexPath) as! TImeTableViewCell
let target = list[indexPath.row]
cell.dateLabel.text = "\(target.date), \(target.hoursFromGMT)시간"
cell.locationLabel.text = target.location
cell.ampmLabel.text = target.ampm
cell.timeLabel.text = target.time
//
// if let dataLabel = cell.viewWithTag(100) as? UILabel{
// dataLabel.text = "\(target.date), \(target.hoursFromGMT)시간"
// }
// if let locationLabel = cell.viewWithTag(200) as? UILabel{
// locationLabel.text = target.location
// }
// if let ampmLabel = cell.viewWithTag(300) as? UILabel{
// ampmLabel.text = target.ampm
// }
// if let timeLabel = cell.viewWithTag(400) as? UILabel{
// timeLabel.text = target.time
//
// }
return cell
}
}
import Foundation
class Region {
let title: String
var countries: [String]
init(title: String, countries: [String]) {
self.title = title
self.countries = countries
}
static func generateData() -> [Region] {
var list = [Region]()
let localeList = [Locale(identifier: "en_US"), Locale(identifier: "ko_KR")]
for l in localeList {
for id in Locale.isoRegionCodes {
guard let name = l.localizedString(forRegionCode: id) else {
continue
}
guard let chosung = name.chosung else {
continue
}
let region = list.first { $0.title.compare(chosung, options: .diacriticInsensitive) == .orderedSame }
if let region = region {
region.countries.append(name)
} else {
list.append(Region(title: chosung, countries: [name]))
}
}
}
for item in list {
item.countries.sort()
}
list.sort(by: { $0.title < $1.title } )
return list
}
}
extension String {
private var koreanUnicodeRange: (Int, Int) {
return (0xAC00, 0xD7AF)
}
var chosung: String? {
guard utf16.count > 0 else {
return nil
}
let chosungList = ["ㄱ","ㄲ","ㄴ","ㄷ","ㄸ","ㄹ","ㅁ","ㅂ","ㅃ","ㅅ","ㅆ","ㅇ","ㅈ","ㅉ","ㅊ","ㅋ","ㅌ","ㅍ","ㅎ"]
let code = utf16[utf16.startIndex]
if code >= UInt16(koreanUnicodeRange.0) && code <= UInt16(koreanUnicodeRange.1) {
let unicode = code - UInt16(koreanUnicodeRange.0)
let chosungIndex = Int(unicode / 21 / 28)
return chosungList[chosungIndex]
}
return String(first!)
}
}
import UIKit
class SectionHeaderAndFooterViewController: UIViewController {
@IBOutlet weak var listTableView: UITableView!
let list = Region.generateData()
override func viewDidLoad() {
super.viewDidLoad()
}
}
extension SectionHeaderAndFooterViewController: UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return list.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return list[section].countries.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
let target = list[indexPath.section].countries[indexPath.row]
cell.textLabel?.text = target
return cell
}
}
extension SectionHeaderAndFooterViewController: UITableViewDelegate {
}
extension SectionHeaderAndFooterViewController: UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return list.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return list[section].countries.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
let target = list[indexPath.section].countries[indexPath.row]
cell.textLabel?.text = target
return cell
}
// sectionHeader에 title이 표시되게해보자.
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return list[section].title
}
}
override func viewDidLoad() {
super.viewDidLoad()
listTableView.register(UITableViewHeaderFooterView.self, forHeaderFooterViewReuseIdentifier: "header")
}
extension SectionHeaderAndFooterViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerview = tableView.dequeueReusableCell(withIdentifier: "header")
headerview?.textLabel?.text = list[section].title
headerview?.detailTextLabel?.text = "lorem ipsum"
return headerview
}
func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
if let headerview = view as? UITableViewHeaderFooterView {
headerview.textLabel?.textColor = .systemBlue
headerview.textLabel?.textAlignment = .center
// backgroundcolor 설정하기
if headerview.backgroundView == nil {
let v = UIView(frame: .zero)
v.backgroundColor = .secondarySystemFill
v.isUserInteractionEnabled = false
headerview.backgroundView = v
}
}
}
}
아래와 같이 view를 만들고 datasource delegate을 설정해준다.
Region 코드를 사용한다.
import Foundation
class Region {
let title: String
var countries: [String]
init(title: String, countries: [String]) {
self.title = title
self.countries = countries
}
static func generateData() -> [Region] {
var list = [Region]()
let localeList = [Locale(identifier: "en_US"), Locale(identifier: "ko_KR")]
for l in localeList {
for id in Locale.isoRegionCodes {
guard let name = l.localizedString(forRegionCode: id) else {
continue
}
guard let chosung = name.chosung else {
continue
}
let region = list.first { $0.title.compare(chosung, options: .diacriticInsensitive) == .orderedSame }
if let region = region {
region.countries.append(name)
} else {
list.append(Region(title: chosung, countries: [name]))
}
}
}
for item in list {
item.countries.sort()
}
list.sort(by: { $0.title < $1.title } )
return list
}
}
extension String {
private var koreanUnicodeRange: (Int, Int) {
return (0xAC00, 0xD7AF)
}
var chosung: String? {
guard utf16.count > 0 else {
return nil
}
let chosungList = ["ㄱ","ㄲ","ㄴ","ㄷ","ㄸ","ㄹ","ㅁ","ㅂ","ㅃ","ㅅ","ㅆ","ㅇ","ㅈ","ㅉ","ㅊ","ㅋ","ㅌ","ㅍ","ㅎ"]
let code = utf16[utf16.startIndex]
if code >= UInt16(koreanUnicodeRange.0) && code <= UInt16(koreanUnicodeRange.1) {
let unicode = code - UInt16(koreanUnicodeRange.0)
let chosungIndex = Int(unicode / 21 / 28)
return chosungList[chosungIndex]
}
return String(first!)
}
}
import UIKit
class SectionIndexViewController: UIViewController {
@IBOutlet weak var listTableView: UITableView!
let list = Region.generateData()
override func viewDidLoad() {
super.viewDidLoad()
}
}
extension SectionIndexViewController: UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return list.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return list[section].countries.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
let target = list[indexPath.section].countries[indexPath.row]
cell.textLabel?.text = target
return cell
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return list[section].title
}
}
override func viewDidLoad() {
super.viewDidLoad()
listTableView.sectionIndexColor = UIColor.systemBlue
listTableView.sectionIndexBackgroundColor = UIColor.secondarySystemBackground
listTableView.sectionIndexTrackingBackgroundColor = UIColor.systemYellow
}