I have a collection View that I made horizontal scrolling. It has 3 rows and 5 columns. Once I enabled horizontal scrolling the cells fill up going down the columns instead of across the rows. For example i have an array 1,2,3,4,5,6,8,9,10,11,12,13,14,15,16 that i am using to fill my collection view. The cells would look like this
1,4,7,10,13,16
2,5,8,11,14
3,6,9,12,15
How can I fix this.
That's the default behavior of horizontal.If you want you can sort the array in some way so it'll be displayed the way you want it.
Like this:
var array = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
var horizontalSortedArray = [Int]()
let columns = 5
let rows = 3
for i in 0..<columns {
for j in 0..<rows {
horizontalSortedArray.append(array[j*columns+i])
}
}
print(horizontalSortedArray)
// [1, 6, 11, 2, 7, 12, 3, 8, 13, 4, 9, 14, 5, 10, 15]
Now if you use this new array as your data source in horizontal mode it'll be displayed like this:
1 ,2 ,3 ,4 ,5
6 ,7 ,8 ,9 ,10
11,12,13,14,15
Related
I have two grid let say grid a and grid b. Value of grid a is (1, 2, 3, 4, 5, ... 50) and in grid b (3, 5, 10, 25) .
I need when I click row with value 10 in grid b, then grid a will automatically scroll to row with value 10 too. Below code I have been try :
gridRoomStatus?.setContentOffset(CGPoint.init(x: 0, y: 0), animated: true)
self.gridRoomStatus?.reloadColumns(self.gridRoomStatus?.columns)
I have that code to make grid a go to the top when grid b is clicking. But it's still not solving my problem. I can't get a specific point for row with specific value. In UITableView there are tableView.rectForRow(at: indexPath) but I can't find similar function with that in Shinobi data Grid. How to do that?
Here I solved this problem, example :
let rowHeight = 50
let rowIndexToSnapTo = 20
grid.setContentOffset(CGPoint(x: 0, y: rowHeight * rowIndexToSnapTo))
I am trying to create a general diffing function for doing batch updates in table views. Basically, it takes two arrays of sections, each containing an identifier for each section and an identifier for each row in each section, and calculates which sections to delete, insert or move and which individual rows to delete, insert or move. I.e., suitable input for deleteSections(_:with:), insertSections(_:with:), moveSection(_:toSection:), deleteRows(at:with:), insertRows(at:with:) and moveRow(at:to:).
I thought this could be done quite generally, but it seems I've found limits to what can be done, and I wanted to just check if I'm missing something.
So let's say I have two sections, "Fruits" and "Vegetables", containing one element each: "Banana" in Fruits, "Carrot" in Vegetables.
Let's say I want to switch so that suddenly a banana is a vegetable and a carrot is a fruit. Easy enough, I generate a moveRow(at: [0, 0], to: [1, 0] and a moveRow(at: [1, 0], to: [0, 0]) and update my data source accordingly; the rows will switch place.
Now, let's say instead I want the two sections to switch places. I will do a moveSection(0, toSection: 1) (or I can do moveSection(1, toSection: 0, or both - it doesn't matter in this case). Ok. The carrot row now moves along with the vegetables sections and the banana with the fruits.
But now... I'd like to do both of these things at the same time. The sections should switch places, but the items should stay put - or, to put it differently, they should switch which logical section they belong to but keep their physical row. This does not seem possible.
I've tried to do the moveSection and at the same time (== within the same beginUpdate/endUpdate) do moveRow(at: [0, 0], to: [0, 0]) and moveRow(at: [1, 0], to: [1, 0]), but these calls to moveRow are just the no-ops they appear to be.*
I've also tried to do deleteRows/insertRows to make the rows stay where they are; that instead gives me a crash:
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Attempt to create two animations for cell'
reloadRows doesn't work either; afaik that does the same as an deleteRows/insertRows pair.
So, basically my question is:
Am I missing something? Is this possible?
(Not interested in workarounds like reconfiguring the cells or headers with the new data, I don't actually have a situation where I need to do this, I just want to know!)
Demo code if anyone wants to play around.
(* Actually, they are just no-ops when combined with both moveSection(0, toSection:1) and moveSection(1, toSection:0); if only one of these are performed, we get that internal consistancy crash!)
Change your switchBothNoOp() into this:
func switchBothNoOp() {
switch state {
case .first:
sections = [("Fruits", ["Banana"]),
("Vegetables", ["Carrot"])]
case .second:
sections = [("Vegetables", ["Banana"]),
("Fruits", ["Carrot"])]
}
tableView.moveSection(0, toSection: 1)
}
Then you move rows later using another begin/end updates block. For example:
func update() {
tableView.beginUpdates()
// Pick on of these:
// switchItems()
// switchSections()
switchBothNoOp()
// switchBothCrash()
tableView.endUpdates()
tableView.beginUpdates()
tableView.moveRow(at: [0, 0], to: [1, 0])
tableView.moveRow(at: [1, 0], to: [0, 0])
tableView.endUpdates()
}
var replycount = replies.count
var startingTag = 10
for subview in self.personView.subviews {
if replycount > 0 {
subview.viewWithTag(startingTag)?.backgroundColor = .green
replycount = replycount - 1
startingTag = startingTag + 1
}
}
}
I'm pulling a number from a server (replycount) and trying to represent the number by coloring some views on the screen. I've got 10 bubbles across the bottom, and if replycount was 4, starting from the left I'd want 4 of the bubbles to have a green background color, and the rest to remain their default black.
What I'm trying to do with the above code is to grab the reply count which I"m doing successfully, my first bubble starts at a tag of 10 and goes up to 19, and if the reply count is more than 0, meaning there is a reply, I'm wanting to take the first tag of 10, make it green, then move on to the next tag of 11, minus from the reply count, and keep going until there are no more replies.
The only time the code below works is if I comment out
replycount = replycount - 1
and change viewWithTag(startingTag) to viewWithTag(10) and hardcode in the number. If either of those two things aren't done the view's color is not changed.
Is there a better way to do this, or any ideas why I'm running into this issue?
Skip looping through subviews and just do self.view.viewWithTag? Although I'm just assuming all of the bubbles are in the same view, and not each in a different subview.
Although I would probably have written it something like this for clarity:
var replycount = replies.count
for tag in 10 ..< (10 + replycount) {
self.view.viewWithTag(tag)?.backgroundColor = .green
}
I want to draw clickable grid objects inside zoomable scrollview taken datas from remote json data my example remote json file data under below;
Json data explode means;
0 = Empty object not show object in view
1 = Show object with title and background not empty object
[
{
"Base": "A",
"Seats": "A1*0*,A2*1*,A3*1*,A4*1*,A5*0*,A6*0*"
},
{
"Base": "B",
"Seats": "B1*1*,B2*1*,B3*1*,B4*0*,B5*0*,B6*0*,B7*1*"
},
{
"Base": "C",
"Seats": "C1*0*,C2*0*,C3*0*,C4*0*,C5*0*,C6*0*,C7*1*,C8*1*,C9*1*,C10-C11*1*"
}
]
Also i have remote json parsing codes i take json arrays to my under below arrays successfuly ;
var Base = [""]
var Seats = [""]
Will shows in my zoomable scrollview inside that json like under below;
1 2 3 4 5 6 7 8 9 10 11
A A2 A3 A4
B B1 B2 B3 B7
C C7 C8 C9 C10-C11
Not empty objects like an A2,A3,A4 must be square width : 20 height : 20 with green background clickable object. When i click in my view i can change backgroud color it to like red etc..
Also C10-C11 MUST BE double widthx 2 so that seats double seats.you can see comming json value.
How can i do this i try collectionview but dont have zoom feature ? I think i need to do with cgrect somethings ?
Thank you !
Is your json file format fixed or can it be customised ? it does not seems well prepared for what you expect.
You don't need to have A B C section and repeat the Section name in the grid item. As in the Battleship game, the name of each cell is expressed by the column and row title. So if you can format this:
[{ "A":"0","1","1","1","0","0"... },{ "B":"1","1","1","0"...},{"C" : ..."0","1","1","1",**"2"**}]
(NB: this works only if seat can be only doubled horizontally)
Now you create two arrays : One with bases names by getting the dictionary (from the JSON) keys:
let bases = jsonDict.allKeys
and an other with all the data in it: let seats = jsonDict
Now you should loop twice:
First in the base array then in the seats array for each base entry.
Each time you check the value of seats[bases[index in base loop]][index in the seat loop] to get the value. If it is 0 you continue, if it is 1 you create a square view and add it to the scrollview. the same if it 2 with a doubled width square view.
To set the position of the square view (or rectangle if value is 2) you use the loop index. Bases are rows and seats are columns. The anchor point of the square view will be x:0 for index 0 in the seats loop and y:0 for the A base, will be x:20 * loop index of the seats loop and y: 20 * loop index of the bases loop. Width will be value * 20 and height always 20.
And then you manage clicks and colour states in the square view itself by handling touch event on it.
Don't forget to set the contentSize of your scrollview to CGSize(width: base[0].count * 20, height: bases.count * 20
Let me know if it help.
I have a UICollectionView and I'm running into an issue with getting the padding between cells. In theory, I should be able to divide the screen by 4, and I can get a cellsize that has 4 images which perfectly take up the screen width. But, it chooses not to do that. Instead it creates 3 images with HUGE padding as shown below:
_cellSize = CGSizeMake(UIScreen.mainScreen().bounds.width/4,UIScreen.mainScreen().bounds.width/4)
So I decreased the cell size a bit to create some padding, and this was closer but I need about half this padding:
_cellSize = CGSizeMake(UIScreen.mainScreen().bounds.width/4.4,UIScreen.mainScreen().bounds.width/4.4)
So I tried making the cells a bit bigger and it rolls over to the next row and puts 3 items with HUGE padding again.
_cellSize = CGSizeMake(UIScreen.mainScreen().bounds.width/4.3,UIScreen.mainScreen().bounds.width/4.3)
Can I specify the padding between cells without it deciding that if the padding is below "x" amount that it creates a new row instead? Like can I set the threshold padding before a new row to say, 0?
I want to make it this thin:
You only need to do the correct calculation that includes the spaces you want to the edges as well as the space between the cells. For instance, if you want 3 cells across with 5 points to the edges and between the cells, you should have something like this,
override func viewDidLoad() {
super.viewDidLoad()
var layout = self.collectionView.collectionViewLayout as UICollectionViewFlowLayout
layout.sectionInset = UIEdgeInsetsMake(0, 5, 0, 5);
layout.minimumInteritemSpacing = 5; // this number could be anything <=5. Need it here because the default is 10.
layout.itemSize = CGSizeMake((self.collectionView.frame.size.width - 20)/3, 100) // 20 is 2*5 for the 2 edges plus 2*5 for the spaces between the cells
}