How do i add spacing between each cell here -
for i in 0...50 {
let cell = UIView()
cell.backgroundColor = .lightGray
cell.frame = CGRect(x: Double(i) * Double(32.52), y: 90, width: 350, height: 500)
view.addSubview(cell)
}
Because with the code above the view looks like this
Your cells are much too wide for the increment you're using horizontally. Your increment offsets them by 32.52 (why the fractional part?) and the views have a width of 350.
So your view spans will be:
From X up to
------ -----
0 350
32.52 403.52 (overlapping from 32.53 to 350)
65.04 456.04 (overlapping from 65.04 to 403.52)
and so on ...
You probably meant to use a narrower frame width (or a larger increment).
The spacing will be the difference between your increment and the frame width.
For example: an increment of 32 with a width of 30 will give you a 2 pixel gap between views.
Related
I am trying to improve my app to looks the same on every iPhone device. I started designing on iPhone 8 plus.
I added 3 buttons to the view and set 3 constraints(width/height and aspect ratio) 1st button = Width:300 Height: 65 aspect ratio
2nd button = Width: 175 Height: 65 aspect ratio
3rd button = Width: 200 Height: 65 aspect ratio
I added them to stackView and set some options(axis: vertical , alignment: center ,distribution: fill proportionally, spacing: 19)
Now i want to set the stackView so it will looks exactly the same on every device.. When i add 3 constraints (top/right/left + aspect ratio) i dont get the results i want. Any idea what i am doing wrong?
Set stackView distribution = FillEqually , then when you give stackView these constraints
top , left , right and aspect ratio
any item will have it's height resized , and give each one the aspect you want so the width will stretch accordingly
I have a UICollectionView that I want to use as a grid. When I receive an ordered pair I want to move a CAShapeLayer circle to the appropriate spot. I have 400 UICollectionView cells to form a 20x20 grid (+, +). Is there a way to do this with UICollectionView?
This what my grid looks likeā¦
The green dot represents ordered pair (12, 2). I got the dot in the right spot by guessing and checking what CGPoint would correspond with (12, 2).
Any help or suggestions are appreciated!
Thanks in advance!
Something like this should work assuming your grid goes to the edges of your UICollectionView. You might need to adjust the CGPoint by half the width of your circle.
let width = collectionView.bounds.width
// dimensions of the grid
let xdim: CGFloat = 20
let ydim: CGFloat = 20
// the grid coordinates of your point
let x: CGFloat = 12
let y: CGFloat = 2
let point = CGPoint(x: x * width / xdim, y: (ydim - y) * width / xdim)
The collectionView shows cells without any problem except the spacing, some spacing are not equal to others, they are a little bit bigger than others. Even I set margin = 0, some spacing still comes out.
Here is the code:
let margin = 1
let cellSize = (size.width-margin*(cellsPerRow+1)) / cellsPerRow
let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
layout.sectionInset = UIEdgeInsets(top: margin, left: margin, bottom: margin, right: margin)
layout.itemSize = CGSize(width: cellSize, height: cellSize)
layout.minimumInteritemSpacing = margin
layout.minimumLineSpacing = margin
Thanks.
You need to define the cell size based on maximum (integer) width/height that fits your whole area, then take the "leftover" (=area_width_or_height - (cell_size*cell_amount) ) and divide it by two to get the size of margins you need to leave to left/right/top/bottom to make the grid even. Now you get your cells slightly random based on whether you round to lower or higher number.
In my app, for one screen, I am setting the size and centering the background of a SpriteKit node. For example, I'm setting the size of the background subview as follows:
backgroundNode.size = self.frame.size
While this is working on the iPhone 6 Plus, the smaller screen/lower resolution of the iPhone 5 means the default size of the other nodes makes is too large to fit within their scene.
How can I force other nodes conform to the size of the background node?
I wanted to divide each subview's size by the background subview's size, but math operations can't be done directly on the size property.
SpriteKit scenes (SKScene) contain nodes, nodes (SKNode), which have size and position properties (of type CGSize and CGPoint, respectively).
UIKit UIView.frame and bounds properties are a CGRect structs comprised of the same CGSize and CGPoint type structs.
So it really helps to understand how to work with CGRect, CGSize and CGPoint.
Be aware, CGRect, CGSize and CGPoint as structs, in Swift, are always passed by value to functions, not by references as classes are, so you can't modify fields inside the structs passed into a function, and have them propagate back to the caller's copy of the struct without taking extra steps.
Because size and position properties are compound types, you can't use them like scalars in simple in math and logic operations; as they contain multiple properties.
For example:
CGSize contains width and height properties,
CGPoint consists of x and y properties.
If want to divide size, you have to access width and height properties of the CGSize struct individually.
You can assign the size in one operation (i.e. single constructor):
node.size = CGSize(
width: node.size.width / backgroundNode.size.width,
height: node.size.height / backgroundNode.size.height)
Or you could do it discretely:
node.size.width = node.size.width / backgroundNode.size.width
node.size.height = node.size.height / backgroundNode.size.height
When dealing with CGRect fields, sometimes it's useful to deal with it as a single entity. For example,
view.frame = CGRect(x: 0, y: 0, width: 10, height: 10)
Others sometimes it's more practical to set size and origin properties separately:
view.frame.origin = CGPoint (x: 0, y: 0)
view.frame.size = CGSize (width: 10, height: 10)
or even:
view.frame.origin.x = 0
view.frame.origin.y = 0
view.frame.size.width = 10
view.frame.size.height = 10
It's also worth knowing about the "zero" static property of each of the struct, as convenient crisp shorthand equivalents:
CGRect .zero ... CGRect (x: 0, y: 0, width: 0, height: 0)
CGPoint.zero ... CGPoint (x: 0, y: 0)
CGSize .zero ... CGSize (width: 0, height: 0)
If you do a lot of adjusting of size and position, to reduce code bloat, you might consider borrowing or developing convenient Swift extensions to `CGRect, CGSize and CGPoint` to simplify applying delta values to sizes or origins.
I have a UIImageView as part of a UICollectionViewCell that I would like to use to visually display a quantity (like a progress bar). In this case the ImageView and its offset represent the percentage remaining of a given item represented by the cell.
Imagine an image of water inside a glass. When the glass is full you see all of the water texture. When the glass is half full, you see half of the water image. so on and so forth...
I want to adjust the top margin of the ImageView based on the percentage remaining. for example:
var image : UIImageView
var item = inventoriedItem(percentageRemaining : 100)
var pctLeft = item.percentageRemaining
pctLeft = 42
// PSEUDOCODE:
image.topMarginOffset = 100 - pctLeft
You could try adjusting the frame of the UIImageView based on the percentage left.
var image = UIImageView(frame: CGRect(x: 20, y: 10, width: 50, height: 100))
var pctLeft = 0.42
//assuming you want a vertical progress bar (like a glass of water).
image.frame = CGRect(x: 20, y: 10 + (100 * (1 - pctLeft)), width: 50, height: 100 * pctLeft)
Here I programmatically push the Y value down based on the reduced size of the bar. Let me know if this is what you were looking for...