How to align data points in shinobichart based on bars frame in iOS - ios

I'm developing an iOS application and using shinobichart for iOS to display data. But I'm stuck with positioning the datapoints outside or inside the bar based on the bar frame.
I'm stuck in positioning the data point labels inside the bar or outside the bar based on bar frame. If bar is big enough to accommodate the data point I need to position the data point inside bar or else outside the bar as in the below image
In - (void)sChart:(ShinobiChart *)chart alterDataPointLabel:(SChartDataPointLabel *)label forDataPoint:(SChartDataPoint *)dataPoint inSeries:(SChartSeries *)series we need to update data points if we wish as per shinobi documentation. But what logic can help to solve such an alignment of data points.
Also I tried to with the following official shinobi example to align data point aside https://www.shinobicontrols.com/blog/customizable-datapoint-labels
But unable to modify for the requirement.
Please help to solve this riddle.

The best way for you to achieve this is to use the alterDataPointLabel method as you have mentioned. I would do something like this:
func sChart(chart: ShinobiChart!, alterDataPointLabel label: SChartDataPointLabel!, forDataPoint dataPoint: SChartDataPoint!, inSeries series: SChartSeries!) {
if Int(label.text!) > [YOUR CUT OFF VALUE]
{
label.frame.origin.y += 15
label.textColor = UIColor.whiteColor()
}
else
{
label.frame.origin.y -= 15
label.textColor = UIColor.blackColor()
}
}
This works best if you know the values your chart is going to be displayed. However as a more generic way of achieving it I would recommend comparing the y value of the data label's origin against y value of the chart canvas. Then for example you could set the it so it appears within the column if it the series was 90% of the canvas?

Related

How to always get rounded corners (corner-radius) on a view that has dynamic height?

I'm rather new to iOS programming.
I was wondering what is the proper way to achieve permanently rounded corners (via the attribute view.layer.cornerRadius) for a view that has dynamic height.
In Android, we would just set the cornerRadius to an absurdly high number like 1000. This would result in the view always having rounded corners regardless of how tall or short it was.
Unfortunately, when I tried to do the same thing in iOS, I realized that an overly large value for cornerRadius results in the view being drawn in a distorted way - or straight up just disappearing from the layout altogether.
Anyone have any insights into this problem? Thanks.
Easy to achieve this with RxSwift by observing Key Path.
extension UIView{
func cornerHalf(){
clipsToBounds = true
rx.observe(CGRect.self, #keyPath(UIView.bounds))
.subscribe(onNext: { _ in
self.layer.cornerRadius = self.bounds.width * 0.5
}).disposed(by: rx.disposeBag)
}
}
Done in init method, the code seems simpler by declaration , instead of being distributed two parts. Especially, the logic is widely used in the project.
Call like this:
let update: UIButton = {
let btn = UIButton()
// more config
btn.cornerHalf()
return btn
}()

UIslider and UI progress view embedded

I'm trying to build a slider embedded in a progress bar, so that slider's minimum image settles with the progress bar 'progress image' and the user can slide only inside the 'progress track image'.
Something like image below:
As in the image,
green section is a progress view
section right to the red (minimum slider value image) is a slider &
should dynamically adjust to the 'progress image' and should hide the
'progress track'
I hav tried to set the
minimumvalueimage
of slider programatically as below:
override func trackRectForBounds(bounds: CGRect) -> CGRect {
// keeps original origin and width, changes height, you get the idea
let customBounds = CGRectMake(7, 0, 180, 15)
super.trackRectForBounds(customBounds)
return customBounds
}
Is this a correct way to do this task, please suggest me something. I'm stuck here, and not in the right track..
if I'm not clear about anything please let me know...Any process are appreciated as long as within swift.
I was stuck because of the logic to implement this. Finally I got an way to set the progress bar and slider with the percentage i.e multiplier.
Firstly, I set the progress bar to 100%,
Then, I set the multiplier, which will set the percentage of progress-bar UI limit and set it to its position right next to the
slider.
And finally, The red icon is minimum value image for slider which sticks to the progress-bar trailing margin, (programmatically constraints).
Or, via Storyboard You could just position it to the view in-between first(i.e. ProgressView) and second(i.e. SliderView) view.
So, the UISlider will get its position from 100% of the view width - % covered by the progress-bar
EDIT: - I may provide the code sample, if required.. just let me know. :)
Happy Coding: )

Centering node vertically in horizontal ASStackLayout

I'm wonder what is the correct way to center textNode inside vertical ASSStackNode which is inside horizontal ASStackNode without setting any sizes?
I've tried different options with ASCenterLayout / ASRelativeLayout around vertical layout, flewGrow, flexShrink.
Only possible way that I see is static layout with minimum height around vertical layout. But wanna find if there are another way.
Images to better picture:
My layout structure:
What I get when one of text fields is empty:
What I want to see:
If your ASTextNode is empty or nil. Isn't mean node not exist. If you want hide node if it empty, you must write a simple logic for it. For exlude it Spec from calculation. What i use on ADK1.9:
- (ASLayoutSpec *)layoutSpecThatFits: (ASSizeRange)constrainedSize
{
NSMutableArray *arrayOfChildren = [NSMutableArray new];
[arrayOfChildren insertObject:self.titleNode];
if (self.textNode.text.length > 0) {
[arrayOfChildren insertObject:self.textNode];
}
ASStackLayoutSpec *verticalElementCoreStack = [ASStackLayoutSpec stackLayoutSpecWithDirection:ASStackLayoutDirectionVertical spacing:8
justifyContent:ASStackLayoutJustifyContentCenter alignItems:ASStackLayoutAlignItemsStretch
children:arrayOfChildren];
return verticalElementCoreStack;
}

Update segmented control in ios without change interface

when I update segmented control text, the interface (segment's width) changed and cut some letters.
[segmentedcontoll setTitle:#"test" forSegmentAtIndex:1];
segmentedcontoll.apportionsSegmentWidthsByContent = YES;
How can I solve this ?
EDIT:
It looks like your content has outgrown the dimensions of the standard UISegmentedControl.
If you are okay with smaller font, it's possible to set the entire control to have a smaller font point size, seen here.
Another option is to configure the segments the other supported way.. With images. It's a little bit of a hack, but you can create images on the fly with the UIView Snapshotting API of views/labels configured however you want and set images for each segment instead of using text. This would allow you to create 2 line labels with fixed widths and set images for each section to be images generated from the label as the content changes. More work, but you would still be using the standard class.
The last option, which might work the best for you, is to create some other custom control that does what you would like. After all, UISegmentedControl really is just a nice button container. And it does somewhat seem like you are using the control in a non-standard way - both as a control and an input form section.
Others have gone this route before and created alternatives that you can use.
You can create a separate class as below,
class CustomSegmentedControl: UISegmentedControl {
//code for creating multi line
override func didMoveToSuperview()
{
for segment in subviews
{
for subview in segment.subviews
{
if let segmentLabel = subview as? UILabel
{
segmentLabel.numberOfLines = 0 //just change here the number of lines and check it.
}
}
}
}
}
and create an outlet in your viewcontroller as,
// Initialize
let items = ["Purple", "Green", "New Segment"]
let customSC = CustomSegmentedControl(items: items)
use customSC and do what ever you want to do, similar to segmentedControl object.

How to trace which image is currently seen in my Uiscrollview?

I am new to iOS.
I am working on UIScrollView based application. I have 3 images in UIScrollView.
I have 2 UIButtons which have selector method for Facebook and Twitter sharing.
I want to share image which is currently seen in UIScrollView to Facebook & Twitter.
I am stuck at extracting image at current scroll point.
After Googling I think something like UIPageController is the solution for me.
But I do not have any idea about how to implement it.
Please help me sort it out. Thank You!
I would say you have multiple options here, this is really a design question.
An easy (but also not very elegant) approach would be to fetch the current offset of the scroll view using its contentOffset property (depending on whether your scroll view scrolls horizontically or vertically, you have ease to use the x or y value of the contentOffset).
Next, you get the position values from your image views (again either myImageView.frame.origin.x or myImageView.frame.origin.y) and you can then calculate which of the image views is currently in the offset of the scroll view.
You can use a page controller (basically, you allow the user to end its scrolling on specific index).
Or when the user touches a button, you can retrieve the contentOffset of the scrollView and compare this value with the origin of the frame your images.
Assume, you created your images with these frames:
image1.frame = CGRectMake(0,0,320,250);
image2.frame = CGRectMake(0,250,320,250);
image3.frame = CGRectMake(0,500,320,250);
Now when you get the action:
-(IBAction)share:(id)sender {
CGPoint offset = self.scrollView.contentOffset;
if (offset.y < 250) {
//First image selected
}else if (offset.y > 500) {
//Third image selected
} else {
//Second image selected
}
}

Resources