why is content in UICollectionViewCell located incorrectly? - ios

I have next code in controller, which set frame of UICollectionViewCell:
let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
layout.sectionInset = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
layout.itemSize = CGSize(width: self.view.frame.size.width / 3.8, height: self.view.frame.size.width / 3.8)
layout.minimumInteritemSpacing = 0
layout.minimumLineSpacing = 0
layout.scrollDirection = .vertical
devicesCollectionView.collectionViewLayout = layout
Chunk of code in delegate method, which call cell's method, which set data in it:
if let deviceCell = cell as? DevicesCollectionViewCell , let devices = room?.devices, let roomName = room?.roomName {
deviceCell.setDeviceInfoInCell(device: devices[indexPath.item], roomName: roomName, width: self.view.frame.size.width / 3.8)
}
chunk of code in cell's class:
self.frame = CGRect(x: self.frame.origin.x, y: self.frame.origin.y, width: width, height: width)
self.stateImageView.frame = CGRect(x: self.frame.origin.x + width - (width / 3), y: self.frame.origin.y, width: width / 3, height: width / 3)
self.lightImageView.frame = CGRect(x: self.frame.origin.x + 10, y: self.frame.origin.y + 10, width: width / 3, height: width / 3)
self.sensImageView.frame = CGRect(x: self.frame.origin.x + 10, y: self.frame.origin.y + 10, width: width / 5, height: width / 5)
self.humdityImageView.frame = CGRect(x: self.frame.origin.x + 10, y: self.frame.origin.y + sensImageView.frame.size.height + 15, width: width / 5, height: width / 5)
But when my CollectionView is showed, imageviews inside placed incorrectly, sometimes I didn't see them. Why they gets incorrect coordinates?
Screenshots: only one picture in one cell
and here icons goes anywhere:
Updating
according the comments I'm trying to use layoutIfNeeds and adding this method to my cell's class:
override func layoutSubviews() {
self.layoutIfNeeded()
self.stateImageView.layoutIfNeeded()
self.sensImageView.layoutIfNeeded()
self.humdityImageView.layoutIfNeeded()
self.lightImageView.layoutSubviews()
}
But it is don't solved my problem, and now labels goes anywhere too. Please help me. New screenShot:

Related

Change UILabel.frame when orientation changes using viewWillTransition

I programmatically create a set of buttons in the viewDidLoad() of my UIInputViewController. I am trying to change the size of these buttons when the orientation changes from landscape to portrait and vice-versa.
I am trying to do this by using
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator)
but when I go through the same code I used to create my buttons in viewDidLoad() with only the UIlabel.frame change to accommodate the new height and width, the view is not updated. Do I have to first remove the buttons and load them from scratch or is there another method to do this?
Below is the full code from the function.
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
let width = screensize.width
var height = CGFloat(141)
let sizey = screensize.height
switch sizey {
case 1366:
height = CGFloat(383-15)
case 1112:
height = CGFloat(320-15)
case 812:
height = CGFloat(141-15)
case 1024:
height = CGFloat(320-15)
case 736:
height = CGFloat(226-15)
case 667:
height = CGFloat(216-15)
case 568:
height = CGFloat(216-15)
case 768:
height = CGFloat(420-15)
default:
height = CGFloat(141-15)
}
connection.frame = CGRect(x: 0, y: 0, width: width/2, height: 15)
serialNum.frame = CGRect( x: width/2, y: 0, width: width/2, height:15)
plus.frame = CGRect(x:0, y: 15, width: width/5,height: height/4)
minus.frame = CGRect(x:0, y: height/4+15, width: width/5,height: height/4)
left.frame = CGRect(x:0, y: height/2+15, width: width/5,height: height/4)
nextKeyboardButton.frame = CGRect(x:0,y: 3*height/4+15, width: width/5,height: height/4)
num1.frame = CGRect(x:width/5, y: 15, width: width/5,height: height/4)
num4.frame = CGRect(x:width/5, y: height/4+15, width: width/5,height: height/4)
num7.frame = CGRect(x:width/5, y: height/2+15, width: width/5,height: height/4)
comma.frame = CGRect(x:width/5, y: 3*height/4+15, width: width/5,height: height/4)
num2.frame = CGRect(x:width*2/5,y: 15, width: width/5,height: height/4)
num5.frame = CGRect(x:width*2/5,y: height/4+15, width: width/5,height: height/4)
num8.frame = CGRect(x:width*2/5,y: height/2+15, width: width/5,height: height/4)
num0.frame = CGRect(x:width*2/5,y: 3*height/4+15, width: width/5,height: height/4)
num3.frame = CGRect(x:width*3/5,y: 15, width: width/5,height: height/4)
num6.frame = CGRect(x:width*3/5,y: height/4+15, width: width/5,height: height/4)
num9.frame = CGRect(x:width*3/5,y: height/2+15, width: width/5,height: height/4)
period.frame = CGRect(x:width*3/5,y: 3*height/4+15, width: width/5,height: height/4)
back.frame = CGRect(x:width*4/5, y: 15, width: width/5, height: height/4)
spaceBar.frame = CGRect(x: width*4/5, y: height/4+15, width: width/5, height: height/4)
right.frame =
CGRect(x: width*4/5, y: height/2+15, width: width/5, height: height/4)
returnKey.frame = CGRect(x:width*4/5, y: height*3/4+15, width: width/5, height: height/4)
self.view.addSubview(spaceBar)
self.view.addSubview(num1)
self.view.addSubview(num2)
self.view.addSubview(num3)
self.view.addSubview(num4)
self.view.addSubview(num5)
self.view.addSubview(num6)
self.view.addSubview(num7)
self.view.addSubview(num8)
self.view.addSubview(num9)
self.view.addSubview(num0)
self.view.addSubview(plus)
self.view.addSubview(minus)
self.view.addSubview(back)
self.view.addSubview(left)
self.view.addSubview(right)
self.view.addSubview(period)
self.view.addSubview(comma)
self.view.addSubview(nextKeyboardButton)
self.view.addSubview(returnKey)
You need to use the ‘size’ argument that you get in the ‘viewWillTransition’ method to set the new ‘width’ and ‘sizey’ properties in stead of ‘screensize’.
You shouldn't call addSubview on orientation change if you've already added the buttons in viewDidLoad. Updating the frame should be enough.
Since you have added these set of buttons in the viewDidLoad() of your UIInputViewController, you don't need to use addSubview in viewWillTransition to size method.
Even after rotating the device still you are using the old screen size.
Change
let width = screensize.width
let sizey = screensize.height
To
let width = UIScreen.main.bounds.width
let sizey = UIScreen.main.bounds.height
Or
let width = size.width
let sizey = size.height

Reduce height of a UIView from the top

I am simply trying to set frame of a UIView, but when you try to reduce the height of view, it will be reduced from the bottom of the view, not the top. How can I change hight of view from the top of it not bottom ?
customView = CGRect(x: 0, y:0 , width: self.view.frame.width , height: self.view.frame.height - reduceHeightSize)
You can update frame.origin.y as much as the height.
if reduceHeightSize is positive;
customView = CGRect(x: self.view.frame.origin.x, y: self.view.frame.origin.y + reduceHeightSize , width: self.view.frame.width , height: self.view.frame.height - reduceHeightSize)
if you store it negative reduceHeightSize;
customView = CGRect(x: self.view.frame.origin.x, y: self.view.frame.origin.y - reduceHeightSize , width: self.view.frame.width , height: self.view.frame.height + reduceHeightSize)
It would be better to just keep amount of the size not the direction.
You need to do like...
customView = CGRect(x: 0, y:reduceHeightSize , width: self.view.frame.width , height: self.view.frame.height - reduceHeightSize)
customView = CGRect(x: 0, y:0 , width: self.view.frame.width , height: self.view.frame.height - reduceHeightSize)
The problem of your code is that you change Height in CGRect. and you want to change top position of view so you need to change position of also y of your view so finally your code will be
customView = CGRect(x: 0, y: reduceHeightSize , width: self.view.frame.width , height: self.view.frame.height - reduceHeightSize)
If I understand your question correctly, that's probably because your view is not constrained/anchored at the bottom and thus defaulting to reduce on the top. Try adding a bottom constraint.
I just figured it out what I need:
customView.frame = CGRect(x: 0, y: self.view.frame.origin.y - reduceHeightSize , width: self.view.frame.width , height: self.view.frame.height + reduceHeightSize)

Adding UIButtons in an arc

I'm trying to make a button that when tapped forms an arc of options. I'm able to draw the options on a diagonal line (see image below) but can't figure out how to display them in an arc. Any suggestions?
What I'm getting
Code
let resourceObjects = ["sprite", "shape", "text", "function", "sound", "variable", "list"]
let radius : CGFloat = 120
var shiftX : CGFloat = 0
var shiftY : CGFloat = radius
// x^2 + y^2 = radius
for o in resourceObjects {
let cell = UIButton()
cell.frame = CGRect(x: sender.frame.origin.x + shiftX, y: sender.frame.origin.y + 50 - shiftY, width: screenWidth, height: 30)
self.view.addSubview(cell)
let img = UIImageView()
img.frame = CGRect(x: 0, y: 0, width: 20, height: 20)
img.image = UIImage(named: String(o) + ".png")
cell.addSubview(img)
let lbl = UILabel()
lbl.frame = CGRect(x: 27, y: 0, width: screenWidth - 60, height: 30)
lbl.font = UIFont.systemFont(ofSize: 12)
lbl.text = o
lbl.sizeToFit()
lbl.frame = CGRect(x: 27, y: 0, width: lbl.frame.width, height: lbl.frame.height)
cell.addSubview(lbl)
cell.frame = CGRect(x: sender.frame.origin.x + shiftX, y: sender.frame.origin.y + 50 - shiftY, width: lbl.frame.width + 27, height: 30)
shiftX += radius / CGFloat(resourceObjects.count)
shiftY -= radius / CGFloat(resourceObjects.count)
options.append(cell)
}
Use trig to calculate the positions: vary your angle from 0 to 2 pi for a full circle. Use a fraction of that range for a part of a circle.
x = cos(angle) * radius + origin.x
y = sin(angle) * radius + origin.y

AutoLayout for programmatically created uiview element

When i try to create an uiview with loading text and activityindicator, even though it looks centered in iphone 6, it is not centered in iphone 5.
How can i use auto layout for this programatically created UIView ?
I am trying to center this uiview in all screen sizes
boxView = UIView(frame: CGRect(x: TableView.frame.midX - 60, y: TableView.frame.midY - 15, width: 180, height: 50))
boxView.backgroundColor = UIColor.blackColor()
boxView.alpha = 0.5
boxView.layer.cornerRadius = 10
var activityView = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.WhiteLarge)
activityView.frame = CGRect(x: 0, y: 0, width: 50, height: 50)
activityView.startAnimating()
var textLabel = UILabel(frame: CGRect(x: 60, y: 0, width: 200, height: 50))
textLabel.textColor = UIColor.whiteColor()
textLabel.text = "Loading"
boxView.addSubview(activityView)
boxView.addSubview(textLabel)
TableView.addSubview(boxView)
EDIT: I tried this and it seems working good
var bounds: CGRect = UIScreen.mainScreen().bounds
var width:CGFloat = bounds.size.width
var height:CGFloat = bounds.size.height
boxView = UIView(frame: CGRect(x: width/2 - 90, y: height/2 - 100, width: 180, height: 50))

Swift: Setting width and height within a UIButton class

So I have a 60x60 button on my storyboard and set a class for it.
class CustomRedButton: UIButton {
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.layer.cornerRadius = 0.5 * self.bounds.size.width
self.backgroundColor = UIColor.redColor()
self.titleLabel!.font = UIFont(name: "Futura", size: 25)
self.titleLabel!.textAlignment = .Center
}
}
What I want to do is adjust the size of the button, and the font in it, based on the size of the screen.
Use view.bounds.maxX and view.bounds.maxY within the ViewController when you initialize it.
this is what I'm doing, but it only changes the width, not the height or the font size.
button1 = UIButton(frame: CGRect(x: 0, y: 0, width: (view.bounds.maxX / 2) - 10, height: 50))
button1.center = CGPoint(x: view.bounds.midX - button1.bounds.width / 2 - 5, y: view.bounds.maxY - 160)
button2 = UIButton(frame: CGRect(x: 0, y: 0, width: (view.bounds.maxX / 2) - 10, height: 50))
button2.center = CGPoint(x: view.bounds.midX + button1.bounds.width / 2 + 5, y: view.bounds.maxY - 160)
button3 = UIButton(frame: CGRect(x: 0, y: 0, width: (view.bounds.maxX / 2) - 10, height: 50))
button3.center = CGPoint(x: view.bounds.midX - button1.bounds.width / 2 - 5, y: view.bounds.maxY - 100)
button4 = UIButton(frame: CGRect(x: 0, y: 0, width: (view.bounds.maxX / 2) - 10, height: 50))
button4.center = CGPoint(x: view.bounds.midX + button1.bounds.width / 2 + 5, y: view.bounds.maxY - 100)
To do it for the height set the height to (view.bounds.maxY / 16 (or whatever number its up to you)) - 10 (spacing between buttons times 2) and change the center point to reflect the changes in height
To do the same for font size use view.bounds.maxX and divide it by something like 40. You get the idea.

Resources