Reputation: 111
I want to select intermediate cells automatically. If I select start time and end time, like as a screenshot, here I select 01:00 as start time and 06:00 as end time. And I want to select automatically select time 02:00, 03:00, 04:00, 05:00, it's is as example...
Maybe my client want to select 01:00 as start time and 21:00 as end time accordingly, automatically should be selected all the time.
I have three time range, it's need for me to display different time for working and for each range time i have three prices. For example:
First time and price made for morning.
Second time and price made for day.
Third time and price made for evening.
Can I to do and how to do it? Maybe there are frameworks which will help me to do this quickly?
My code is here:
class BookingViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {
var bookingHall: Halls?
var timeIntervalArray: [String] = []
var timeIntervalArrayTwo: [String] = []
var timeIntervalArrayThree: [String] = []
var selectedTimeIntervalArray: [String] = []
var bookingAmountOfHallArray: [Int] = []
var sumOfBookingAmount: Int = 0
var allArrayTimesAndPrices: [(time: String, price: Int)] = [] // ARRAY FOR COLLECT ALL TIMES AND ALL PRICES
lazy var timeFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "HH:mm"
return formatter
}()
override func viewDidLoad() {
super.viewDidLoad()
configureSelectedDateAndTime()
collectionView.allowsMultipleSelection = true
// MORNING TIME RANGE
if let timeRange = generateTimeRange() {
self.timeIntervalArray = timeRange
self.collectionView.reloadData()
} else {
// Handle error
}
// DAY TIME RANGE
if let timeRangeTwo = generateTimeRangeTwo() {
self.timeIntervalArrayTwo = timeRangeTwo
self.collectionView.reloadData()
} else {
// Handle error
}
// EVENING TIME RANGE
if let timeRangeThree = generateTimeRangeThree() {
self.timeIntervalArrayThree = timeRangeThree
self.collectionView.reloadData()
} else {
// Handle error
}
if let hall = bookingHall {
allArrayTimesAndPrices =
timeIntervalArray.map({ (time: $0, price: hall.price) }) +
timeIntervalArrayTwo.map({ (time: $0, price: hall.priceSecond) }) +
timeIntervalArrayThree.map({ (time: $0, price: hall.priceThird) })
}
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return allArrayTimesAndPrices.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "timeCell", for: indexPath) as! BookingTimeCell
cell.timeLabel.text = allArrayTimesAndPrices[indexPath.item].time
cell.priceLabel.text = "\(allArrayTimesAndPrices[indexPath.item].price) руб."
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let selectedCell = collectionView.cellForItem(at: indexPath)
selectedIndexesAndBackgroundColor(cell: selectedCell!, indexPath: inde xPath)
}
func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
let deselectedCell = collectionView.cellForItem(at: indexPath)
deselectedIndexesAndBackgroundColor(cell: deselectedCell!, indexPath: indexPath)
}
// the selected time
func selectedIndexesAndBackgroundColor(cell: UICollectionViewCell, indexPath: IndexPath) {
let timeToAdd = allArrayTimesAndPrices[indexPath.item].time
selectedTimeIntervalArray.append(timeToAdd)
}
// cancelled time
func deselectedIndexesAndBackgroundColor(cell: UICollectionViewCell, indexPath: IndexPath) {
let timeToRemove = allArrayTimesAndPrices[indexPath.item].time
let indexTime = selectedTimeIntervalArray.index(of: timeToRemove)
selectedTimeIntervalArray.remove(at: indexTime!)
}
// MORNING
func generateTimeRange() -> [String]? {
var result = [String]()
if let hall = bookingHall {
guard var startTime = timeFormatter.date(from: hall.firstStartTimeToIncreasePrice) else { return nil }
guard let endTime = timeFormatter.date(from: hall.firstEndTimeToIncreasePrice) else { return nil }
while startTime <= endTime {
result.append(timeFormatter.string(from: startTime))
startTime = Calendar.current.date(byAdding: .hour, value: 1, to: startTime)!
}
}
return result
}
// DAY
func generateTimeRangeTwo() -> [String]? {
var result = [String]()
if let hall = bookingHall {
guard var startTime = timeFormatter.date(from: hall.secondStartTimeToIncreasePrice) else { return nil }
guard let endTime = timeFormatter.date(from: hall.secondEndTimeToIncreasePrice) else { return nil }
while startTime <= endTime {
result.append(timeFormatter.string(from: startTime))
startTime = Calendar.current.date(byAdding: .hour, value: 1, to: startTime)!
}
}
return result
}
// EVENING
func generateTimeRangeThree() -> [String]? {
var result = [String]()
if let hall = bookingHall {
guard var startTime = timeFormatter.date(from: hall.thirdStartTimeToIncreasePrice) else { return nil }
guard let endTime = timeFormatter.date(from: hall.thirdEndTimeToIncreasePrice) else { return nil }
while startTime <= endTime {
result.append(timeFormatter.string(from: startTime))
startTime = Calendar.current.date(byAdding: .hour, value: 1, to: startTime)!
}
}
return result
}
}
Upvotes: 0
Views: 176
Reputation: 291
Create below global properties:
var selectedIndexPath:IndexPath! // store selected indexpath
var arrSelectedIndexPath = [IndexPath]() // array of selected indexpath
After then
extension ViewController: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return timeArray.count
}
// -------------------------------------------------------------------------------------------
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: (self.view.frame.size.width - 60) / 7, height: (self.view.frame.size.width - 60) / 7)
}
// -------------------------------------------------------------------------------------------
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
// dequeue cell
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionViewCell
// assign text to label
cell.lblTitle.text = self.timeArray[indexPath.item]
if self.arrSelectedIndexPath.contains(indexPath) {// if arrSelectedIndexPath contain indexpath then change backgrond color of label
cell.lblTitle.backgroundColor = UIColor(red: 81.0/255.0, green: 182.0/255.0, blue: 186.0/255.0, alpha: 1.0)
}else { // else set it to default color white
cell.lblTitle.backgroundColor = UIColor.white
}
// return collection view cell
return cell
}
// -------------------------------------------------------------------------------------------
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
if self.selectedIndexPath == nil { // if selected indexpath nil then assign first indexpath
self.selectedIndexPath = indexPath
self.arrSelectedIndexPath.removeAll() // remove all items from array
self.collectionView.reloadData() // reload CollectionView
}else {
if self.arrSelectedIndexPath.count == 0 { // if arrSelectedIndexPath.count == 0 then
if self.selectedIndexPath.item < indexPath.item { // check first selected indexpath is smaller then end indexpath
// fill all intermediate cell
for i in self.selectedIndexPath.item...indexPath.item {
self.arrSelectedIndexPath.append(NSIndexPath(item: i, section: 0) as IndexPath)
}
// reload collection view and update background color
self.collectionView.reloadData()
// reset first selected indexpath
self.selectedIndexPath = nil
}else { // else select first selected indexpath
self.selectedIndexPath = indexPath
}
}else { // else remove all items from
self.arrSelectedIndexPath.removeAll()
self.collectionView.reloadData()
self.selectedIndexPath = indexPath
}
}
}
// -------------------------------------------------------------------------------------------
}
Hope it works for you!
Upvotes: 1
Reputation: 16456
Have two global objects for indexPaths
var selectedRowOne:IndexPath? <br>
var selectedRowTwo:Indexpath?
After that in didSelectItemAt
if selectedRowOne == nil {
// Start of range is empty !!
selectedRowOne = indexPath;
// Logic for select the row
} else if selectedRowTwo == nil {
// End of range is empty
selectedRowTwo = indexPath
var indexPathToBeSelected :[IndexPath] = []
for i in selectedRowOne!.row ..< selectedRowTwo!.row {
indexPathToBeSelected.append(IndexPath(item: i, section: 0))
}
// Select indexPathToBeSelected logic
}
As your code is too confusing to I can't write code for one case . so Now You have to manage one case where where both selectedRowOne
and selectedRowTwo
is selected and user tap on any of cell.
Then you have to check if selected indexpath.row <selectedRowOne.row
then selectedRowOne = indexpath
Secondly else if
indexpath.row > selectedRowOne.row && indexpath.row < selectedRowTwo.row
then selectedRowOne = indexpath
and at last condition
else if
indexpath.row > selectedRowTwo.row
Then selectedRowTwo = indexpath
And after all apply cell selection logic for range between selectedRowOne
and selectedRowTwo
you need to take care of de select cell also if two cells are selected and if I Deselect first or second you need to manage selectedRowOne
and selectedRowTwo
properly
Hope it is helpful to you
Upvotes: 1
Reputation: 2154
create one property to store selectedIndexPath
var selectedItem: IndexPath?
,
then assign it's value for first selected item.
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
guard let selectedItem = selectedItem else{
selectedItem = indexPath
return
}
//loop for selecting items between current selected item and previous selected item.
for i in selectedItem.row...indexPath.row {
let selectedCell = collectionView.cellForItem(at: IndexPath(row: i, section: indexPath.section))
selectedIndexesAndBackgroundColor(cell: selectedCell!, indexPath: inde xPath)
}
}
and do the same in didDeSelectItemAt
for deselecting items accordingly.
Upvotes: 0