Troubleshooting UIKit display issues - ios

I have a very strange issue where a chart (SwiftChart) is not being displayed (is not visible/rendered) when the project is built and run.
Some background:
XCode 8 (project was originally and XCode 7 project)
Objective C project/ViewControllers
A swift file to render the chart (have tried calling this from viewDidLoad & viewDidLayoutSubviews)
Storyboard containing all ui elements
Using CocoaPods
The 'print' code you see in Swift outputs 'null'
The UIView where the chart is to be rendered exists within the storyboard and is setup as follows
The code being called is:
let chart = Chart()
print(chart.window?.frame.width)
print(chart.window?.frame.height)
let data = [(x: 0.0, y: 0), (x: 3, y: 2.5), (x: 4, y: 2), (x: 5, y: 2.3), (x: 7, y: 3), (x: 8, y: 2.2), (x: 9, y: 2.5)]
let series = ChartSeries(data: data)
series.area = true
chart.xLabels = [0, 3, 6, 9, 12, 15, 18, 21, 24]
chart.xLabelsFormatter = { String(Int(round($1))) + "h" }
chart.add(series)
Visually I see nothing. I'm struggling to figure out where the problem might be so any pointers greatly appreciated

You uave to initialize it with a frame when creating it programmatically since it's a UIControl subclass. It appears their first code example is wrong but they explain it correctly in the next. All on-screen views need a frame at a minimum.
But if you already have a view of this class in your storyboard you need an outlet to point to it. Your first line of code creates a new one, so you're not talking to the one you set up, but an improperly created off-screen one.
So add an outlet and connect it to your view so you can talk to it.

Related

Swift Charts Library, when first Loaded, highlighted value already

enter link description here
I used Charts/danielgindi..
When a graph is selected, the highlight works properly. But what I want is to highlight the center graph on the first screen when no graph is selected.
chartView.highlightValue(x: 3, dataSetIndex: 3, dataIndex: 3)
chartView.highlightValue(Highlight(x: 3, dataSetIndex: 3, stackIndex: 3))
I wrote the code in the same way as above, but it failed.
solution
let midPoint = CGPoint(x: chartView.bounds.midX, y: chartView.bounds.midY)
let h = chartView.getHighlightByTouchPoint(midPoint)
chartView.highlightValue(h, callDelegate: true)

iOS13+ Creating a constant button on top of every screen

I maintain an app SDK that contains a button which should always be displayed on top of all screens in the application, but this functionality broke with iOS 13+ which seems to have changed some internals. The button disappears after changing from the first screen.
// My code that does not work anymore
var applicationWindow: UIWindow? = UIApplication.shared.keyWindow
...
button.frame = CGRect(x: 0, y: 0, width: 94, height: 73)
applicationWindow!.addSubview(button)
I saw similar posts on SOF suggesting code like
UIApplication.shared.windows.first(where: { $0.isKeyWindow })? but it doesn't work for me, and I'm struggling to create and manage a second UIWindow, any code sample would be really appreciated as I'm only a maintainer and I don't work actively on iOS anymore.

Working around SwiftUI Path crash in Xcode 11 beta 5

Apple broke Path in Xcode 11 beta 5:
A known issue in Xcode 11 beta 5 causes your app to crash when you use the Path structure.
So I'm trying to work around this using CGMutablePath:
var body: some View {
GeometryReader { geometry in
let path = CGMutablePath()
path.addRect(CGRect(x: 0, y: 0, width: 100, height: 100))
return Path(path)
}
}
This draws a square.
When I try to change the color as follows:
var body: some View {
GeometryReader { geometry in
let path = CGMutablePath()
path.addRect(CGRect(x: 0, y: 0, width: 100, height: 100))
return Path(path).fill(Color.purple)
}
}
I get:
Cannot convert return expression of type 'GeometryReader<_>' to return type 'some View'
Function declares an opaque return type, but has no return statements in its body from which to infer an underlying type
I'm not sure what return type to use? I tried Path but evidently fill doesn't return another Path.
I tried View but I get:
Protocol 'View' can only be used as a generic constraint because it has Self or associated type requirements
I tried some View but it didn't seem to even parse.
The iOS 13 beta 7 release notes say it's fixed in Xcode 11 beta 6, so we just have to wait for that to be released. Hopefully tomorrow!
From the release notes :
Resolved Issues
Using the Path structure no longer causes your app to crash if you’re using the SDKs included in Xcode 11 beta 6 and later. (53523206)
It still will crash... Path is too broken! But if you are curious how you can get to compile successfully, you can do something like this:
struct MyShape: View {
#State private var flag = false
var body: some View {
return GeometryReader { (geometry) -> AnyView in
let path = CGMutablePath()
path.addRect(CGRect(x: 0, y: 0, width: 100, height: 100))
return AnyView(Path(path).fill(Color.purple))
}
}
}
It will crash on Path(path)

Shonobi Data Grid scroll to a specific row

I have two grid let say grid a and grid b. Value of grid a is (1, 2, 3, 4, 5, ... 50) and in grid b (3, 5, 10, 25) .
I need when I click row with value 10 in grid b, then grid a will automatically scroll to row with value 10 too. Below code I have been try :
gridRoomStatus?.setContentOffset(CGPoint.init(x: 0, y: 0), animated: true)
self.gridRoomStatus?.reloadColumns(self.gridRoomStatus?.columns)
I have that code to make grid a go to the top when grid b is clicking. But it's still not solving my problem. I can't get a specific point for row with specific value. In UITableView there are tableView.rectForRow(at: indexPath) but I can't find similar function with that in Shinobi data Grid. How to do that?
Here I solved this problem, example :
let rowHeight = 50
let rowIndexToSnapTo = 20
grid.setContentOffset(CGPoint(x: 0, y: rowHeight * rowIndexToSnapTo))

iOS dynamic UI in simple terms?

This may be too basic or require rephrasing. I am in the process of learning Swift and iOS programming and have developed a basic application that runs successfully on my iPhone 5. The app consists of a label, a button, and a UIImageView. It looks the way I want it to on my iPhone 5.
I figured most of this out by just playing around and so I am creating all these elements programatically. The code looks like this:
let banner = UILabel(frame: CGRect(x: 10, y: 10, width: 300.0, height: 75.0))
let button = UIButton(frame: CGRect(x: 45, y: 75, width: 235.0, height: 60.0))
let imageView = UIImageView(frame: CGRect(x: 22, y: 150, width: 280.0, height: 410.0))
And then I configure them in viewDidLoad to make them show stuff.
Now the question...how to I make them all the right size when running on different devices? I can load up the app on my iPad Mini but it's all scrunched over to the left of the view. So I need to do some kind of dynamic layout but not sure where to start.
All help appreciated!
Rather than creating the view sizes explicitly with initWithFrame: constructors, you can programmatically create and NSLayoutConstraints to your views to automatically layout your views, the same as if you used Auto Layout with the Interface Builder. See Apple's Auto Layout Guide for more details.

Resources