SubView added to View but not showing - swift

I'm trying to show a subview that has been added to a view, but it does not show up when the button is pressed.
I have tried setting isOpaque to 1, alpha to 1, isHidden to false (without needing to press the button) and have checked that I have run view.addSubview(). I have also found out that the subview is not hidden at all but the background is white (it is supposed to be blue or red).
code to add subviews
//setup
viewBGKRect = CGRect(x: 20, y: 20, width: 984, height: 660)
viewBGK = UIView(frame: viewBGKRect)
viewBGK.backgroundColor = UIColor(red: 139.0, green: 206.0, blue: 231.0, alpha: 1.0)
viewBGK.alpha = 1
viewBGK.isOpaque = true
viewRGKRect = CGRect(x: 20, y: 20, width: 984, height: 660)
viewRGK = UIView(frame: viewRGKRect)
viewRGK.backgroundColor = UIColor(red: 240.0, green: 177.0, blue: 187.0, alpha: 1.0)
viewRGK.alpha = 1
viewRGK.isOpaque = true
//isHidden is set to false when the buttons are pressed
viewBGK.isHidden = true
viewRGK.isHidden = true
view.addSubview(viewBGK)
view.addSubview(viewRGK)
code to show subviews
#IBAction func goalkeeper(_ sender: UIButton) {
switch sender.tag {
case 0:
// blue
viewBGK.isHidden = false
viewRGK.isHidden = true
return
default:
viewBGK.isHidden = true
viewRGK.isHidden = false
return
}
}
I expect a blue/red rectangle to appear at the top of the screen but it does not show.

Nevermind I found the answer:
UIColor RGB is from 0-1 not 0-255 the colors should be
(blue)
UIColor(red:0.55, green:0.81, blue:0.91, alpha:1.0)
and
(red)
UIColor(red:0.94, green:0.69, blue:0.73, alpha:1.0)
not
(blue)
UIColor(red: 139.0, green: 206.0, blue: 231.0, alpha: 1.0)
and
(red)
UIColor(red: 240.0, green: 177.0, blue: 187.0, alpha: 1.0)
i feel really dumb now.

If you're going to utilize custom colors, it might be easier to declare them somewhere other than in a view controller. One approach would be to declare them in an extension. To do this, you would do the following:
Create a new Swift file and name it UIColor+Extension.swift
Inside the new file, add the following code:
extension UIColor {
static var customBlue: UIColor {
return #colorLiteral(red: 0.5450980392, green: 0.8078431373, blue: 0.9058823529, alpha: 1)
}
static var customRed: UIColor {
return #colorLiteral(red: 0.9411764706, green: 0.6941176471, blue: 0.7333333333, alpha: 1)
}
}
I didn't type those colors out. I simply typed return Color Literal and it showed a white rounded rectangle. When I clicked on the rectangle, I saw this:
Then, I clicked the "Other" button and I typed in the RGB values:
Lastly, you want to avoid writing repetitive code (DRY = don't repeat yourself). Here's the updated code:
//setup
viewBGKRect = CGRect(x: 20, y: 20, width: 984, height: 660)
viewBGK = UIView(frame: viewBGKRect)
viewBGK.backgroundColor = .customBlue
viewRGKRect = CGRect(x: 20, y: 20, width: 984, height: 660)
viewRGK = UIView(frame: viewRGKRect)
viewRGK.backgroundColor = .customRed
[viewBGK, viewRGK].forEach { view in
view.alpha = 1
view.isOpaque = true
//isHidden is set to false when the buttons are pressed
view.isHidden = true
}

Related

Swift - Problem handeling button selection

I have a floating button in my app that display 5 different buttons. Each of them has a color but initially are gray. When the user selects one of the buttons, all of them hide, and when the user taps again on the floating button, the button that was previously tapped is not gray but with its proper color.
Also the logic would be that the user can tap another one of the buttons to select it, and the previous one would be unselected, as if the user taps on a selected button, it gets unselected.
I'm using cocoa pods for the Floating Button, JJFloatingActionButton, but on the documentation there is no info about this.
func configureActionButton() {
actionButton.overlayView.backgroundColor = UIColor(white: 0, alpha: 0.5)
actionButton.buttonImage = UIImage(systemName: "line.horizontal.3.decrease")
actionButton.buttonColor = UIColor(named: "signoColor")!
actionButton.buttonImageColor = .white
actionButton.buttonImageSize = CGSize(width: 30, height: 30)
actionButton.itemAnimationConfiguration = .slideIn(withInterItemSpacing: 14)
actionButton.itemSizeRatio = CGFloat(0.75)
let item = actionButton.addItem()
item.titleLabel.text = "Button 1"
item.buttonColor = UIColor(red: 254/255.0, green: 224/255.0, blue: 255/255.0, alpha: 1.0)
item.buttonImageColor = UIColor(red: 200/255.0, green: 73/255.0, blue: 203/255.0, alpha: 1.0)
item.imageSize = CGSize(width: 30, height: 30)
item.action = { item in
//This is for the functionality of the button
}
let item2 = actionButton.addItem()
item2.titleLabel.text = "Button 2"
item2.buttonColor = UIColor(red: 254/255.0, green: 224/255.0, blue: 255/255.0, alpha: 1.0)
item2.buttonImageColor = UIColor(red: 200/255.0, green: 73/255.0, blue: 203/255.0, alpha: 1.0)
item2.imageSize = CGSize(width: 30, height: 30)
item2.action = { item in
//This is for the functionality of the button
}
//And I have 3 more buttons
}
This is how the floating button looks like:
I would appreciate some help. I've searched for similar questions but none of them solved this problem. Thank you!

Why are UIViews background color is not updating?

Switch statement works but won't reset view background colours etc.
I have a UIImage (icon) and a UIButton embedded within a UIView (of custom type DropShadowCircleView) as per image below.
When the walking button is tapped a var navigationOption is set to either walking or driving and setupNavigationSelectionView() is executed.
Problem is: case "walking" of the switch works perfectly, but case "driving" doesn't reset the UIView and icon tint color witcback to their original setting eg; background color etc.. any ideas why?
func setupNavigationSelectionView(){
switch navigationOption {
case "walking":
walkingBg.setGradientBackground(colourOne: softGreen, ColourTwo: softBlue)
walkingBg.layer.cornerRadius = walkingBg.frame.width / 2
walkingBg.clipsToBounds = true
walkingIcon.tintColor = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1)
case "driving":
walkingBg.backgroundColor = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1)
walkingBg.layer.cornerRadius = walkingBg.frame.width / 2
walkingBg.clipsToBounds = true
walkingIcon.tintColor = #colorLiteral(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)
default:
break
}
}
EDIT: this is my DropShadowCircleView class
class DropShadowCircleView: UIView {
override func awakeFromNib() {
setupView()
super.awakeFromNib()
}
func setupView(){
self.layer.shadowOpacity = 0.50
self.layer.shadowRadius = 20
self.layer.shadowColor = UIColor.black.cgColor
self.layer.cornerRadius = self.frame.width / 2
}
}
EDIT: This is my setGradientBackground function which is within an extension file to UIView
func setGradientBackground(colourOne: UIColor, ColourTwo: UIColor) {
let gradientLayer = CAGradientLayer()
gradientLayer.frame = bounds
gradientLayer.colors = [colourOne.cgColor, ColourTwo.cgColor]
gradientLayer.locations = [0.0, 1.0]
gradientLayer.startPoint = CGPoint(x: 1.0, y: 1.0)
gradientLayer.endPoint = CGPoint(x: 0.0, y: 0.0)
layer.insertSublayer(gradientLayer, at: 0)
}
You need to remove your gradient layer when you reset your icon.
Add this to your extension UIView:
func removeGradientBackground() {
guard
let idx = layer.sublayers?.index(where: { $0 is CAGradientLayer })
else { return }
layer.sublayers?.remove(at: idx)
}
and call it when you are resetting your icon.

How to change the color of the Mask View?

I am not sure if I understand the concept of Masking correctly but I am trying to recreate the Twitter logo expansion animation in their app:
Twitter Logo expansion
I have this code so far:
class LaunchScreenViewController: UIViewController {
var mask: CALayer!
override func viewDidLoad() {
setUpViewMask()
}
func setUpViewMask() {
mask = CALayer()
mask.contents = UIImage(named: "logo_mask")?.cgImage
mask.contentsGravity = kCAGravityResizeAspect
mask!.bounds = CGRect(x: 0, y: 0, width: 100, height: 100)
mask!.anchorPoint = CGPoint(x: 0.5, y: 0.5)
mask!.position = CGPoint(x: view.frame.size.width/2, y: view.frame.size.height/2)
view.layer.backgroundColor = UIColor(red: 70/255, green: 154/255, blue: 233/255, alpha: 1).cgColor
view.layer.mask = mask
}
}
The output of this is:
How would I change the black background to be blue? I tried doing but it didn't seem to work:
view.layer.backgroundColor = UIColor(red: 70/255, green: 154/255, blue: 233/255, alpha: 1).cgColor
Create an intermediate layer where you apply mask. Set the background of your view to the desired background, and set background color of the intermediate layer to the color that you wish your mask to appear in. Something like this,
view.backgroundColor = UIColor(red: 70/255, green: 154/255, blue: 233/255, alpha: 1) // set background of the view portion that do not include mask
let parentLayer = CALayer()
parentLayer.frame = view.bounds
parentLayer.backgroundColor = UIColor.white.cgColor // sets background of mask
view.layer.addSublayer(parentLayer)
let mask = CALayer()
mask.contents = UIImage(named: "twitter.png")?.cgImage
mask.contentsGravity = kCAGravityResizeAspect
mask.bounds = CGRect(x: 0, y: 0, width: 100, height: 100)
mask.anchorPoint = CGPoint(x: 0.5, y: 0.5)
mask.position = CGPoint(x: view.frame.size.width/2, y: view.frame.size.height/2)
parentLayer.mask = mask
This can be achieved by changing the background color of appDelegate's window...
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.window!.backgroundColor = UIColor.blue

Can't use variable to create custom swift color

I'm trying to use the variables red, green, and blue to create a color that is random, but I get an error that says it can't convert the variable type into a CGFloat.
import UIKit
var red = arc4random_uniform(8) + 1;
var green = arc4random_uniform(8) + 1;
var blue = arc4random_uniform(8) + 1;
let containerView = UIView(frame: CGRect(x: 0.0, y: 0.0, width: 300.0, height: 600.0))
let circle = UIView(frame: CGRect(x: 105.0, y: 215.0, width: 100.0, height: 100.0))
circle.layer.cornerRadius = 50.0
let startingColor = UIColor(red: (253.0/255.0), green: (159.0/255.0), blue: (47.0/255.0), alpha: 1.0)
circle.backgroundColor = startingColor
containerView.addSubview(circle);
Try
let startingColor = UIColor(red: CGFloat(red), green: CGFloat(green), blue: CGFloat(blue), alpha: 1.0)

Does the legend limit the number of titles?

I am using iso-charts to try and draw a pie chart in an iOS app.
No matter what I try, I can't seem to get the full number of titles to draw in the legend.
I have my data set up as:
ages = ["18-", "25-", "35-", "45-", "55-", "65-", "75+"]
agePercentages = [10.0, 20.0, 30.0, 5.0, 10.0, 45.0, 120.0]
My code to setup the pieChart as:
func setPieDefaults(myPieChart: PieChartView) -> PieChartView {
myPieChart.frame = CGRectMake(0, 0, UIScreen.mainScreen().bounds.size.width, UIScreen.mainScreen().bounds.size.width*0.5)
myPieChart.usePercentValuesEnabled = true
myPieChart.holeTransparent = true
myPieChart.holeColor = UIColor.darkPurpleColor()
myPieChart.backgroundColor = UIColor.darkPurpleColor()
myPieChart.rotationAngle = 0.0
myPieChart.rotationEnabled = true
myPieChart.centerTextFont = UIFont(name: "HelveticaNeue-Bold", size:20)!
myPieChart.descriptionText = ""
myPieChart.centerText = "%"
myPieChart.centerTextColor = UIColor.whiteColor()
myPieChart.drawHoleEnabled = true
myPieChart.noDataText = "Loading Data ..."
let legend = myPieChart.legend
legend.font = UIFont(name: "Arial", size: 11)!
legend.textColor = UIColor.whiteColor()
legend.position = .RightOfChart
legend.form = .Circle
return myPieChart
}
And ..
func setChart(dataPoints: [String], values: [Double], myPieView: PieChartView) {
var dataEntries: [ChartDataEntry] = []
for i in 0..<dataPoints.count {
let dataEntry = ChartDataEntry(value: values[i], xIndex: i)
dataEntries.append(dataEntry)
}
var colors = [UIColor]()
switch myPieView {
case genderPieChartView:
colors = [UIColor.blueColor(), UIColor.pinkColor()]
default:
colors = ChartColorTemplates.colorful()
}
let pieChartDataSet = PieChartDataSet(yVals: dataEntries, label: nil)
pieChartDataSet.sliceSpace = 3.0
pieChartDataSet.colors = colors
let pieChartData = PieChartData(xVals: dataPoints, dataSet: pieChartDataSet)
myPieView.animate(xAxisDuration: 2, yAxisDuration: 2)
let pFormatter = NSNumberFormatter()
pFormatter.numberStyle = .PercentStyle
pFormatter.maximumFractionDigits = 0
pFormatter.percentSymbol = ""
pFormatter.multiplier = 1
pieChartData.setValueFormatter(pFormatter)
pieChartData.setValueFont(UIFont(name: "HelveticaNeue-Bold", size: 11)!)
pieChartData.setValueTextColor(UIColor.whiteColor())
myPieView.data = pieChartData
myPieView.drawSliceTextEnabled = false
}
But it won't print any more than 5 of the labels. It's returning the pie-slices perfectly. But not the labels in the legend.
Am I doing something wrong? Thanks in advance for letting me know.
Solved.
In reading the framework docs for the Android version a little better:
The number of entries the automatically generated legend contains
depends on the number of different colors (across all DataSet objects)
as well as on the DataSet labels. The labels of the Legend depend on
the labels set for the used DataSet objects in the chart. If no labels
for the DataSet objects have been specified, the chart will
automatically generate them. If multiple colors are used for one
DataSet, those colors are grouped and only described by one label.
I realised I needed to increase the number of colours in the ChartColorTemplate.colorful() definition to match the number of labels I was trying to use. The current example code comes with only 5 colours defined.
public class func colorful () -> [UIColor]
{
return [
UIColor(red: 193/255.0, green: 37/255.0, blue: 82/255.0, alpha: 1.0),
UIColor(red: 255/255.0, green: 102/255.0, blue: 0/255.0, alpha: 1.0),
UIColor(red: 245/255.0, green: 199/255.0, blue: 0/255.0, alpha: 1.0),
UIColor(red: 106/255.0, green: 150/255.0, blue: 31/255.0, alpha: 1.0),
UIColor(red: 179/255.0, green: 100/255.0, blue: 53/255.0, alpha: 1.0),
UIColor(red: 200/255.0, green: 100/255.0, blue: 53/255.0, alpha: 1.0), // added colour
UIColor(red: 150/255.0, green: 150/255.0, blue: 70/255.0, alpha: 1.0), // added colour
UIColor(red: 84/255.0, green: 78/255.0, blue: 53/255.0, alpha: 1.0), // added colour
]
}
If you have the same problem, then define a lot more colours to meet the needs of the maximum number of labels needed. This will also solve a problem if you try and word-wrap the legend (which I was also facing).