iOS-Charts - X Axis Labels Disappear when Scrolling - swift

I've been working with iOS-Charts from Daniel Gindi and it is a GREAT Framework!
However, I've been struggling with this issue for a long time now. I'm using a BarChart and managed to display the correct Values # the Axis labels.
Now I Don't know why this happens but the labels seem to DISAPPEAR While I'm Scrolling...
Here is a simple example with 2 bars:
And now I Scroll a bit to the Right, and PUFFF! The label is Gone!
// HERE IS MY SETUP CODE:
func setupChartView() {
// Default Texts:
noDataText = ""
chartDescription?.text = ""
// xAxis:
xAxis.drawGridLinesEnabled = false
xAxis.drawAxisLineEnabled = false
xAxis.enabled = true
if (UIScreen.main.nativeBounds.height < iPhone6ScreenHeight) {
xAxis.yOffset = smallScreenYOffset
} else {
xAxis.yOffset = graphLabelYOffset
}
xAxis.labelPosition = .bottom
xAxis.labelFont = defaultTextFont!
xAxis.labelTextColor = .engieChartGrayColor()
xAxis.granularity = 1.0
// Left/Right Axis:
leftAxis.enabled = false
rightAxis.drawGridLinesEnabled = false
rightAxis.drawAxisLineEnabled = false
rightAxis.drawLabelsEnabled = false
rightAxis.drawZeroLineEnabled = false
// Other UI Vars:
dragEnabled = true
drawMarkers = false
drawBordersEnabled = false
clipValuesToContentEnabled = true
drawValueAboveBarEnabled = false
setScaleMinima(4.0, scaleY: 1.0)
legend.enabled = false
doubleTapToZoomEnabled = false
pinchZoomEnabled = false
resetZoom()
scaleXEnabled = false
scaleYEnabled = false
}
Can someone Explain to me why this is?
Thanks, I Really Appreciate the help...

Related

How do i get the entered pin in TVDigitEntryViewController's completion handler in TVOS?

I read about 'TVDigitEntryViewController' in AppleTV OS document. They are given completion handler but i don't know how to use. Share your knowledge if you know.
Text for the entry could be retrieved in entryCompletionHandler
Try using below code to add TVDigitEntryViewController on your view controller.
func addDigitEntryComponent() {
let digitEntryViewController = TVDigitEntryViewController()
digitEntryViewController.isSecureDigitEntry = true
digitEntryViewController.view.backgroundColor = .gray
digitEntryViewController.titleText = "New PIN"
digitEntryViewController.promptText = "Please enter new PIN"
digitEntryViewController.entryCompletionHandler = { (enteredText) in
// Text will be received here in variable "enteredText"
print(enteredText)
}
self.addChild(digitEntryViewController)
digitEntryViewController.view.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(digitEntryViewController.view)
digitEntryViewController.view.topAnchor.constraint(equalTo: self.view.topAnchor).isActive = true
digitEntryViewController.view.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true
digitEntryViewController.view.leadingAnchor.constraint(equalTo: self.view.leadingAnchor).isActive = true
digitEntryViewController.view.trailingAnchor.constraint(equalTo: self.view.trailingAnchor).isActive = true
digitEntryViewController.didMove(toParent: self)
}
I hope this works for you.

Display values outside of the piechart

I am having trouble displaying the values outside of my piechart. Currently the values overlap, is there anyway to improve this? Please see image below.
chartDataSet.valueLinePart1Length = 0.5
chartDataSet.valueLinePart2Length = 1
//set.xValuePosition = .outsideSlice
chartDataSet.yValuePosition = .outsideSlice
func setupPiChart() {
// This will align label text to top right corner
let l = pieChartView.legend
l.horizontalAlignment = .left
l.verticalAlignment = .bottom
l.orientation = .horizontal
l.xEntrySpace = 10
l.yEntrySpace = 0
l.font = self.isPhone ? Typography.robotoRegular14 : Typography.robotoRegular18
self.pieChartView.entryLabelFont = Typography.robotoRegular14
self.pieChartView.drawHoleEnabled = false
self.pieChartView.drawEntryLabelsEnabled = false
self.pieChartView.notifyDataSetChanged()
}

How to programmatically disable constraint when animating

I am have a view with a fixed width anchored to the left. I want this view to animate (moving left to right) by anchoring it to the right (thus removing the left anchor). How do I do this?
I tried setting a priority but I am not sure of the syntax. I also tried to disable the constraint, but that did not work.
fileprivate func sparkle() {
let sparkleView = UIView()
sparkleView.backgroundColor = UIColor.yellow
sparkleView.alpha = 0.5
addSubview(sparkleView)
sparkleView.translatesAutoresizingMaskIntoConstraints = false
sparkleView.topAnchor.constraint(equalTo: topAnchor).isActive = true
sparkleView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
sparkleView.widthAnchor.constraint(equalToConstant: frame.width / 5).isActive = true
sparkleView.leftAnchor.constraint(equalTo: leftAnchor).priority = UILayoutPriorityDefaultLow // Doesn't work
sparkleView.leftAnchor.constraint(equalTo: leftAnchor).isActive = true
layoutIfNeeded()
sparkleView.leftAnchor.constraint(equalTo: leftAnchor).isActive = false // Doesn't work
sparkleView.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true
UIView.animate(withDuration: 2, animations: {
self.layoutIfNeeded()
}) { (_) in
sparkleView.removeFromSuperview()
}
}
Currently, the width constraint gets broken since we are assigning a left and right anchor.
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x6000020b8eb0 UIView:0x7fc846d551d0.width == 15.35 (active)>
-- EDIT --
I have tried creating an instance variable to hold the constraint.
let leftCons = sparkleView.leftAnchor.constraint(equalTo: leftAnchor)
leftCons.isActive = true
I then tried to modify the priority
leftCons.priority = UILayoutPriorityDefaultLow
However, this causes error
'Mutating a priority from required to not on an installed constraint (or vice-versa) is not supported. You passed priority 250 and the existing priority was 1000.'
Instead, I need to just set it as inactive (from the answers)
leftCons.active = false
-- Correct code if interested.. --
fileprivate func sparkle() {
let sparkleView = UIView()
sparkleView.backgroundColor = UIColor.yellow
sparkleView.alpha = 0.5
addSubview(sparkleView)
sparkleView.translatesAutoresizingMaskIntoConstraints = false
sparkleView.topAnchor.constraint(equalTo: topAnchor).isActive = true
sparkleView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
sparkleView.widthAnchor.constraint(equalToConstant: frame.width / 5).isActive = true
let leftCons = sparkleView.leftAnchor.constraint(equalTo: leftAnchor)
leftCons.isActive = true
layoutIfNeeded()
leftCons.isActive = false
sparkleView.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true
UIView.animate(withDuration: 0.5, animations: {
self.layoutIfNeeded()
}) { (_) in
sparkleView.removeFromSuperview()
}
}
You need to create a var
var leftCon:NSLayoutConstraint!
then alter it , you problem is every line create a new constraint
sparkleView.widthAnchor.constraint(equalToConstant: frame.width / 5).isActive = true
sparkleView.leftAnchor.constraint(equalTo: leftAnchor).isActive = true
sparkleView.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true
note: above 3 constraints create a conflict as the view can't be pinned to left and right at the same time with a width constraint that why you see the conflict break => NSLayoutConstraint:0x6000020b8eb0 UIView:0x7fc846d551d0.width == 15.35 (active)
regardless of the active assignment so those
sparkleView.leftAnchor.constraint(equalTo: leftAnchor).priority = UILayoutPriorityDefaultLow // Doesn't work
sparkleView.leftAnchor.constraint(equalTo: leftAnchor).isActive = false // Doesn't work
are on the fly and don't alter the created constraint , so to be
leftCon = sparkleView.leftAnchor.constraint(equalTo: leftAnchor)
leftCon.isActive = true
Regarding this crash
'Mutating a priority from required to not on an installed constraint (or vice-versa) is not supported
you need to set the priority before the activation
leftCon.priority = UILayoutPriorityDefaultLow
leftCon.isActive = true

Updating Constraints programmatically?

I have a subclass of UIView, I want to manipulate a constraint but it does not work.
When pressing a button exchangesViewActivated changes and the functions get called.
var exchangesViewActivated = false {
didSet {
if exchangesViewActivated == true {
setExchangesView()
} else {
setUpLayout()
}
}
}
Die subview and translatesAutoresizingMaskIntoConstraints are set.
func setUpLayout() {
bottomContainer.heightAnchor.constraint(equalToConstant: 500).isActive = true
bottomContainer.leadingAnchor.constraint(equalTo: scrollViewContrainer.leadingAnchor).isActive = true
bottomContainer.trailingAnchor.constraint(equalTo: scrollViewContrainer.trailingAnchor).isActive = true
bottomContainer.topAnchor.constraint(equalTo: configBar.bottomAnchor).isActive = true
bottomContainer.bottomAnchor.constraint(equalTo: scrollViewContrainer.bottomAnchor).isActive = true
}
Now I want to manipulate the constraint by calling this function:
func setExchangesView() {
bottomContainer.bottomAnchor.constraint(equalTo: scrollViewContrainer.bottomAnchor).isActive = false
bottomContainer.heightAnchor.constraint(equalToConstant: 500).isActive = false
bottomContainer.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: 0).isActive = true
}
But this constraint stays activated:
bottomContainer.heightAnchor.constraint(equalToConstant: 500).isActive
Am I missing something? Is it not enough to set a constraint to false to deactivate it? Do I have to call something else?
setUpLayout() is adding new constraints every time you call setUpLayout() method. You must save constraint reference and update it next time.
For example.
// class variable
var bottomConstraint:NSLayoutConstraint? = nil
bottomConstraint = bottomContainer.heightAnchor.constraint(equalToConstant: 500)
bottomConstraint.isActive = true
And later update constraint
bottomConstraint.constant = 100
bottomConstraint.isActive = true
This doesn't deactivate old constraints as it deactivates the newly created ones so do
var heightCon:NSLayoutConstraint!
var botCon:NSLayoutConstraint!
//
heightCon = bottomContainer.heightAnchor.constraint(equalToConstant: 500)
heightCon.isActive = true
botCon = bottomContainer.bottomAnchor.constraint(equalTo: scrollViewContrainer.bottomAnchor)
botCon.isActive = true
Then you can easily reference the constraints and deactivates them and add the new constraints

Diagonal focussing in tvOS using UIFocusGuide

I have 4 UIButtons in my view:
All four are UIButtons with two UIButtons on the left side and another two on the right side. Focus is going from the top button to the bottom button when I select down arrow. I want focus to navigate through all four buttons from top to bottom and again from bottom to top when I press the down arrow and up arrow.
I also want to change the background color of the UIBUtton when it is highlighted(Currently white is coming by default).
I tried below code to navigate the focus but I couldn't get what I wanted.
let focusGuide = UIFocusGuide()
view.addLayoutGuide(focusGuide!)
focusGuide!.rightAnchor.constraintEqualToAnchor(self.btnPlay.rightAnchor).active = true
focusGuide!.topAnchor.constraintEqualToAnchor(self.switchFirst.topAnchor).active = true
focusGuide!.widthAnchor.constraintEqualToAnchor(self.btnPlay.widthAnchor).active = true
focusGuide!.heightAnchor.constraintEqualToAnchor(self.switchFirst.heightAnchor).active = true
focusGuide!.preferredFocusedView = self.switchFirst
in viewdidLoad and
Below code in didUpdateFocusInContext
guard let nextFocusedView = context.nextFocusedView else { return }
switch nextFocusedView {
case self.switchFirst:
self.focusGuide!.preferredFocusedView = self.btnPlay
case self.btnPlay:
self.focusGuide!.preferredFocusedView = self.switchFirst
case self.switchAudioType:
self.focusGuide!.preferredFocusedView = self.btnAdd
case self.btnAddToWishList:
self.focusGuide!.preferredFocusedView = self.switchSecond
Well one simple approach would be to use 4 different focus guides. I've included a very basic image of where they would be. Focus Guide Placement:
// [1] in viewDidLoad
let firstFocusGuide = UIFocusGuide()
view.addLayoutGuide(firstFocusGuide)
firstFocusGuide.leftAnchor.constraintEqualToAnchor(self.btnPlay.leftAnchor).active = true
firstFocusGuide.topAnchor.constraintEqualToAnchor(self.btnPlay.bottomAnchor).active = true
firstFocusGuide.heightAnchor.constraintEqualToAnchor(self.btnPlay.heightAnchor).active = true
firstFocusGuide.widthAnchor.constraintEqualToAnchor(self.switchFirst.widthAnchor).active = true
firstFocusGuide.preferredFocusedView = self.switchFirst
let secondFocusGuide = UIFocusGuide()
view.addLayoutGuide(secondFocusGuide)
secondFocusGuide.rightAnchor.constraintEqualToAnchor(self.switchFirst.rightAnchor).active = true
secondFocusGuide.bottomAnchor.constraintEqualToAnchor(self.switchFirst.topAnchor).active = true
secondFocusGuide.heightAnchor.constraintEqualToAnchor(self.switchFirst.heightAnchor).active = true
secondFocusGuide.widthAnchor.constraintEqualToAnchor(self.switchFirst.widthAnchor).active = true
secondFocusGuide.preferredFocusedView = self.btnPlay
let thirdFocusGuide = UIFocusGuide()
view.addLayoutGuide(thirdFocusGuide)
thirdFocusGuide.leftAnchor.constraintEqualToAnchor(self.btnAdd.leftAnchor).active = true
thirdFocusGuide.bottomAnchor.constraintEqualToAnchor(self.btnAdd.topAnchor).active = true
thirdFocusGuide.heightAnchor.constraintEqualToAnchor(self.btnAdd.heightAnchor).active = true
thirdFocusGuide.widthAnchor.constraintEqualToAnchor(self.switchSecond.widthAnchor).active = true
thirdFocusGuide.preferredFocusedView = self.switchSecond
let fourthFocusGuide = UIFocusGuide()
view.addLayoutGuide(fourthFocusGuide)
fourthFocusGuide.rightAnchor.constraintEqualToAnchor(self.switchSecond.rightAnchor).active = true
fourthFocusGuide.topAnchor.constraintEqualToAnchor(self.switchSecond.bottomAnchor).active = true
fourthFocusGuide.heightAnchor.constraintEqualToAnchor(self.switchSecond.heightAnchor).active = true
fourthFocusGuide.widthAnchor.constraintEqualToAnchor(self.switchSecond.widthAnchor).active = true
fourthFocusGuide.preferredFocusedView = self.btnAdd
Please keep in mind, this will only allow for the Up & Down movements between the four buttons. Not to mention it is a little tedious...Hope that helps!