Swift - Change buttonframe in Xcode - swift

I'm trying to build an app in Xcode and implement buttons to the storyboard.
unfortunately the button frame is quite small in reference to the text inside. How to I change the frame into bigger?
As I am totally new to coding I have no idea - this is the code, but I don't know how to change the frame size and if this is even the right code.
extension UIButton {
func applyDesign() {
self.backgroundColor = UIColor.darkGray
self.layer.cornerRadius = 7
self.layer.shadowColor = UIColor.black.cgColor
self.layer.shadowRadius = 5
self.setTitleColor(UIColor.white, for: .normal)
self.frame.size =
}

If you are creating buttons inside storyboard, you can simply use constraints for frames. If you want to do it manually like you mentioned then you can create a CGRect and assign it to frame, for example:
self.frame = CGRect(x: 100, y: 50, width: 170, height: 30)

Related

How to create floating Tab Bar Swift

I'm trying to create a Pinterest style Tab Bar. Is it possible to customise UITabBar in that way or do you have to write a separate view to sit on top of everything if so how would you do that? It's basically just moved up with rounded corners and a shadow. How would you adjust the width of the tab bar and move it up?
Image of Tab Bar
If you want to make "RoundedTabbar" than you can create one like this ->
import UIKit
class RoundedTabBarController: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
let layer = CAShapeLayer()
layer.path = UIBezierPath(roundedRect: CGRect(x: 30, y: tabBar.bounds.minY + 5, width: tabBar.bounds.width - 60, height: tabBar.bounds.height + 10), cornerRadius: (tabBar.frame.width/2)).cgPath
layer.shadowColor = UIColor.lightGray.cgColor
layer.shadowOffset = CGSize(width: 5.0, height: 5.0)
layer.shadowRadius = 25.0
layer.shadowOpacity = 0.3
layer.borderWidth = 1.0
layer.opacity = 1.0
layer.isHidden = false
layer.masksToBounds = false
layer.fillColor = UIColor.white.cgColor
tabBar.layer.insertSublayer(layer, at: 0)
if let items = tabBar.items {
items.forEach { item in
item.imageInsets = UIEdgeInsets(top: 0, left: 0, bottom: -15, right: 0)
}
}
tabBar.itemWidth = 30.0
tabBar.itemPositioning = .centered
}
}
Don’t forget to type if you are using storyboard, the class name in the Identity inspector.
PS: I'm sharing Emmanuele Corporente's Medium article content as an answer please check the original article & give it some claps!
I created a floating tab bar library. It doesn't look exactly like Pinterest's but you could probably modify the drawing code to change the way it looks.
Here's the repo.
If you want to implement it from scratch, you'll have to create your own view controller subclass, as well as a UIView subclass for the tab bar, and manage the "page" switching yourself. UITabBarController doesn't offer enough customization for this.

How to position an SKLabelNode on top of a UISlider in SpriteKit

I'm using UISliders in my SpriteKit game.
Sometimes I want to pause the game and add some info in an SKLabelNode but I can't find a way to position the SKLabelNode on top of a UISlider.
Here's a simplified example.
override func didMove(to view: SKView) {
let slider = UISlider(frame: CGRect(x: 100, y: 100, width: 300, height: 50))
let label = SKLabelNode(text: "Text Label should be on top of Slider")
label.fontColor = .red
label.verticalAlignmentMode = .top
label.position = CGPoint(x:160, y:self.frame.size.height - 110)
view.addSubview(slider)
self.addChild(label)
slider.layer.zPosition = 1
label.zPosition = 2
}
UISlider remains above SKLabel :-(.
Any help appreciated.
EDIT:
In response to question by #Muffinman2497 "Why not use a UILabel?"
I may have to do that but I'm actually using a custom multi line label that's been designed using spriteKit and SKLabels. So I was hoping for a simple property change rather than a redesign.
Using a UILabel definitely does work though.
let myUILabel = UILabel(frame: CGRect(x: 50, y: 0, width: 300, height: 50))
myUILabel.text = "UILabel would like to obscure UISlider"
myUILabel.backgroundColor = .red
slider.addSubview(myUILabel)
slider.layer.zPosition = 1
myUILabel.layer.zPosition = 2

UIImage in a UIcollectonView issue

I am trying to add a UIImage to the UICollectionViewController by using the following code:
let backgroundImage = UIImageView(frame: CGRect(x: 0, y: 0, width: 430, height: 550))
backgroundImage.image = UIImage(named: "fantasy_football_hero_tile_cropped.png")
backgroundImage.contentMode = UIView.ContentMode.scaleAspectFit
backgroundImage.clipsToBounds = true
self.view.insertSubview(backgroundImage, at: 0)
My issue is that the image is not at the bottom/lowest part of the screen which is what I am trying to achieve... how can I clip it to the bottom?! I am not using story board, can I programmatically anchor the image to the bottom as I could do in a storyboard?
This is especially true since the screen sizes for the phones are different, but the desire is still to have it anchored to the bottom.
you can add programatically. I think you add/insert some views to the self.view that will also affect simple scenario
let backgroundImageV = UIView(frame: CGRect(x: 0, y: 0, width: 430, height: 500))
backgroundImageV.backgroundColor = UIColor.blue
backgroundImageV.contentMode = UIView.ContentMode.scaleAspectFit
backgroundImageV.clipsToBounds = true
self.view.addSubview(backgroundImageV)
let backgroundImageV2 = UIView(frame: CGRect(x: 0, y: 0, width: 430, height: 510))
backgroundImageV2.backgroundColor = UIColor.green
backgroundImageV2.contentMode = UIView.ContentMode.scaleAspectFit
backgroundImageV2.clipsToBounds = true
self.view.insertSubview(backgroundImageV2, at: 0)
let backgroundImage = UIImageView(frame: CGRect(x: 0, y: 0, width: 430, height: 550))
backgroundImage.backgroundColor = UIColor.red
backgroundImage.contentMode = UIView.ContentMode.scaleAspectFit
backgroundImage.clipsToBounds = true
self.view.insertSubview(backgroundImage, at: 0)
Here Red will be bottom Green will be in 1. because you add that red colored view later. So It will work. Can you please show your full code. It will work
One problem here is that self.view for a UICollectionViewController is the UICollectionView. This is a scroll view, so no matter where you put this image view, it is going to move when the scroll view scrolls.
If that isn't what you want, there is a simple solution: set the image view as the collection view's backgroundView. That is a stationary view that forms the background to the collection view no matter how it is scrolled. If you set the image view's contentMode to bottom the image will be centered at the bottom, which seems to be what you are after.

Swift - TableView background image: how to center the image

I want to add a logo as a background image to my tableView. Image size is 50px, 50px.
I tried the code below, but this puts the image lower right corner.
let imageView = UIImageView(image: UIImage(named: "logo"))
imageView.contentMode = .scaleAspectFit
imageView.layer.frame = CGRect(x: self.view.frame.midX, y: self.view.frame.midY, width: 50, height: 50)
let tableViewBackgroundView = UIView()
tableViewBackgroundView.addSubview(imageView)
self.tableView.backgroundView = tableViewBackgroundView
There are a few points about swift that are pretty key:
1) The x and y parameters in CGRect.init(x:y:width:height:) don't refer to the center of the imageView. Instead, they are points in a coordinate system where (0, 0) is the Upper Left Corner of the view that the CGRect is being presented over, and
2) UIImageView actually inherits from UIView, so because of this you can just say
tableView.backgroundView = imageView
You shouldn't have to fiddle around with any CGRects, I believe this code should work just fine, although you may have to fiddle with different contentMode properties to get it to display how you like.
let imageView = UIImageView(image: UIImage(named: "logo"))
imageView.layer.frame = CGRect(x: 0, y: 0, width: 50, height: 50)
imageView.layer.frame.midX = tableView.layer.frame.midX
imageView.layer.frame.midY = tableView.layer.frame.midY
tableView.backgroundView = imageView

UIView Orientation change in Swift

I'm developing an app to display a binary tree.
Each node will be displayed as a subview programatically generated from the ViewController - I run the following from viewDidLayoutSubviews().
let theView = BinaryTreeView(frame: CGRect(x: 0, y: 50, width: width, height: 100))
// let theView = BinaryTreeView(s: "I'm testing")
theView.backgroundColor = .white
theView.addGestureRecognizer(UIPinchGestureRecognizer(target:theView, action:#selector(BinaryTreeView.changeScale(recognizer:))))
self.view.addSubview(theView)
theView.eyesOpen = false
let secondView = BinaryTreeView(frame: CGRect(x: width/2, y: 150, width: width/2, height: 100))
// let theView = BinaryTreeView(s: "I'm testing")
secondView.backgroundColor = .white
secondView.addGestureRecognizer(UIPinchGestureRecognizer(target:secondView, action:#selector(BinaryTreeView.changeScale(recognizer:))))
self.view.addSubview(secondView)
let thirdView = BinaryTreeView(frame: CGRect(x: (width/2)+width/4, y: 250, width: width/4, height: 100))
// let theView = BinaryTreeView(s: "I'm testing")
thirdView.backgroundColor = .white
thirdView.addGestureRecognizer(UIPinchGestureRecognizer(target:thirdView, action:#selector(BinaryTreeView.changeScale(recognizer:))))
self.view.addSubview(thirdView)
The issue is that on orientation change the views repeat each other (above there are three nodes, on orientation change 4 might display.
I looked through Stack and Within my subclassed UIView I added:
self.contentMode = UIViewContentMode.redraw
Within the programatic Subview but the same happens.
Don't worry - I'm going to generate my nodes in a loop later (I'm trying to understand how layout works). Incidentally I found the same happened using a UICollectionView so I seem to be doing something fundamentally wrong.
Change the "target:" to the controller (to self) for all three. Your controller will respond to gestures, not the views themselves. The target will be the same in all three cases.
secondView.addGestureRecognizer(UIPinchGestureRecognizer(target:secondView, action:#selector(BinaryTreeView.changeScale)))
self.view.addSubview(secondView)
becomes
secondView.addGestureRecognizer(UIPinchGestureRecognizer(target:self, action:#selector(BinaryTreeView.changeScale)))
self.view.addSubview(secondView)