How to set valueFormatter for Markers in iOS-charts - ios-charts

For the y-axis we can do something like this:
chartView.leftAxis.valueFormatter = SomeCustomTimeFormatter()
But how do we change the format for markers (the popups that appear when you tap a data point)? I am using BalloonMarker from the sample code.

if you use BalloonMarker from the sample you can update the code in this line
open override func refreshContent(entry: ChartDataEntry, highlight: Highlight)
{
//setLabel(String(entry.y)) //change label value in this line to use your desired format
setLabel(String("\(Int(entry.y)/60):\(Int(entry.y)%60)"
}
open func setLabel(_ newLabel: String)
{
label = newLabel
//.......
}
and set the marker for your chartview
let marker:BalloonMarker = BalloonMarker(color: UIColor(red: 93/255, green: 186/255, blue: 215/255, alpha: 1), font: UIFont(name: "Helvetica", size: 12)!, textColor: UIColor.white, insets: UIEdgeInsets(top: 7.0, left: 7.0, bottom: 25.0, right: 7.0))
marker.minimumSize = CGSize(width: 75.0, height: 35.0)
charts.marker = marker

Related

Swift, Cocoa - how to update view properties when using an NSGraphicsContext?

If I call self.layer? in a draw() method to control the content of an NSView, the view's properties can be updated by the view controller. However, if I create a graphics context for drawing into, this relationship breaks and the view controller no longer updates the view's properties. Why?
In the simple example I provide, if you comment out the guard statement in TestView and call drawBackgroundWithoutContext(), the view is given a background colour when viewDidLoad() is called, and the colour is updated when the mouseDown event occurs.
As soon as a context is declared this breaks, even if you are still calling drawBackgroundWithoutContext().
import Cocoa
class ViewController: NSViewController {
var newR: CGFloat?
var newG: CGFloat?
var newB: CGFloat?
var tview = TestView(frame: NSRect(x: 20, y: 30, width: 100, height: 100))
override func viewDidLoad() {
super.viewDidLoad()
tview.r = 1.0
tview.g = 0.5
tview.b = 0.8
self.view.addSubview(tview)
}
override func mouseDown(with event: NSEvent) {
newR = 0.1
newG = 0.9
newB = 0.0
tview.r = newR
tview.g = newG
tview.b = newB
tview.draw(NSRect(x: 20, y: 30, width: 100, height: 100))
// tview.setNeedsDisplay(NSRect(x: 20, y: 30, width: 100, height: 100))
}
}
class TestView: NSView {
var r: CGFloat?
var g: CGFloat?
var b: CGFloat?
override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
guard let context = NSGraphicsContext.current?.cgContext else {
return
}
// drawBackgroundWithoutContext(red: r, green: g, blue: b)
drawBackgroundWithContext(context: context, red: r, green: g, blue: b)
}
func drawBackgroundWithoutContext(red: CGFloat?, green: CGFloat?, blue: CGFloat?) {
self.layer?.backgroundColor = CGColor(red: red ?? 0.0, green: green ?? 0.0, blue: blue ?? 0.0, alpha: 1.0)
}
func drawBackgroundWithContext(context: CGContext, red: CGFloat?, green: CGFloat?, blue: CGFloat?) {
context.setFillColor(CGColor(red: red ?? 0.0, green: green ?? 0.0, blue: blue ?? 0.0, alpha: 1.0))
context.fill(CGRect(x: 20, y: 30, width: 100, height: 100))
}
}
I read that you should not actually call .draw() in the view controller and the correct method is setNeedsDisplay(), however this had no affect. I have left this call as a comment in the code so you can see what I tried.

How to add custom text on ScreenSaverView in Swift?

Trying to make .saver in swift for MacOS, But don't know how to add custom text or Label on ScreenSaverView class which is the subclass from NSView.
Below is my piece of code, but doesn't work.
private var text: CATextLayer!
override func draw(_ rect: NSRect) {
// Draw a single frame in this function
self.layer?.backgroundColor = .init(red: 142/255, green: 167/255, blue: 125/255, alpha: 1)
text.removeFromSuperlayer()
text.string = "Test"
text.frame = CGRect(x: 100, y: 100, width: 200, height: 100)
text.foregroundColor = .white
text.backgroundColor = .clear
self.layer?.addSublayer(text)
}

SubView added to View but not showing

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
}

Custom Segmented Control with round Background

hope someone can help me....
I've created a UISegmented Control and started to change it to my application design - see screenshot below.
If you guys can see the background of the segmented option, you will see my problem. I managed to change colours, texts and some other small things with the following functions:
What I have so far
extension UISegmentedControl {
func defaultConfiguration(font: UIFont = UIFont(name: "Montserrat-Regular", size: 13)!, textColor: UIColor = UIColor.white, backgroundColor: UIColor = UIColor.clear) {
let defaultAttributes: [NSAttributedString.Key : Any] = [
NSAttributedString.Key(rawValue: NSAttributedString.Key.font.rawValue): font,
NSAttributedString.Key(rawValue: NSAttributedString.Key.foregroundColor.rawValue): textColor,
NSAttributedString.Key(rawValue: NSAttributedString.Key.backgroundColor.rawValue): backgroundColor
]
setTitleTextAttributes(defaultAttributes, for: .normal)
}
func selectedConfiguration(font: UIFont = UIFont(name: "Montserrat-Regular", size: 13)!, textColor: UIColor = UIColor.rgb(red: 52, green: 0, blue: 177), backgroundColor: UIColor = UIColor.white) {
let selectedAttributes: [NSAttributedString.Key : Any] = [
NSAttributedString.Key(rawValue: NSAttributedString.Key.font.rawValue): font,
NSAttributedString.Key(rawValue: NSAttributedString.Key.foregroundColor.rawValue): textColor,
NSAttributedString.Key(rawValue: NSAttributedString.Key.backgroundColor.rawValue): backgroundColor
]
setTitleTextAttributes(selectedAttributes, for: .selected)
}
}
I wanted the background to be bigger and rounded... any ideas what I am missing? When the user clicks, it should see the following
WHAT I NEED:

How to center a custom UIView in a TableView?

I'm trying to center a custom view inside a UITableView and it works fine but when i scroll it doesn't update to the center of the tableview it just stays at the top. Here's my code:
let customView = UIView(frame: CGRect(x: 0, y: 0, width: 150, height: 75))
customView.backgroundColor = UIColor(red: 0/255, green: 174/255, blue: 250/255, alpha: 1.0)
let label = UILabel(frame: CGRect(x: customView.frame.midX, y: customView.frame.midY, width: 150, height: 75))
label.text = "Text"
label.textAlignment = .center
label.font = UIFont(name: "HelveticaNeue-Light", size: 18)
label.textColor = UIColor.white
customView.addSubview(label)
label.center = customView.center
customView.layer.cornerRadius = 4.0
self.view.addSubview(customView)
customView.center = CGPoint(x: self.tableView.bounds.width/2, y: self.tableView.bounds.height/2)
UIView.animate(withDuration: 1.5, animations: {
customView.alpha = 0.0
}) { (success: Bool) in
customView.removeFromSuperview()
}
Any ideas on how to make this work? Thanks.
Add the customView in the tableView and not in the view.
self.tableView.addSubview(customView)