Screen mirror not behaving as expected (Swift) - ios

I'm trying to implement some simple screen mirroring in my swift application but I'm getting undesired behavior. When my code executes, the external display gets the phone view but the iphone screen goes black. Also in the external view it's filled in with black. Here's a screenshot:
Here's my code to setup the external view:
func initializeExternalScreen(external: UIScreen){
self.mirroredScreen = external;
// Find max resolution
var max = CGSize()
var maxScreenMode = UIScreenMode()
for current in self.mirroredScreen.availableModes {
if (current.size.height > max.height || current.size.width > max.width) {
max = current.size;
maxScreenMode = current;
}
}
self.mirroredScreen.currentMode = maxScreenMode;
self.mirroredWindow = UIWindow(frame: self.mirroredScreen.bounds)
self.mirroredWindow.hidden = false
self.mirroredWindow.layer.contentsGravity = kCAGravityResizeAspect
self.mirroredWindow.screen = self.mirroredScreen
self.mirroredScreenView = UIView(frame: self.mirroredScreen.bounds)
self.mirroredScreenView.addSubview(self.view)
self.mirroredWindow.addSubview(self.mirroredScreenView)
}
Any ideas?

Related

Google maps Custom info window not showing properly on iphone X

I am making Uber like application. when user select pick up and destination address, then i draw route between these two addresses.
I have two separate info windows for both Source address and destination address.
This is working fine on my iphone 7 pluse and iphone 6s. But when i try to draw route on iPhone x, the route is drawn successfully but one of the info window is always incorrect.
I have tried every solution. I checked constraints too. everything is fine.
//Destination info window
let infoWindow1 = DestinationInfoWindow.instanceFromNib() as! DestinationInfoWindow
dest.iconView = infoWindow1
infoWindow1.DestinationLabel.text = locationStringwithDetail
infoWindow1.lblRemainingDistance.text = String(self.estimatedDistance.rounded(toPlaces: 1))
self.destinationName = locationStringwithDetail
self.destinationCoordinate = destinationCoordinate
dest.zIndex = 0
dest.position = destinationCoordinate
dest.map = self.mapView
// Source info window
let infoWindow = MapMarkerWindow.instanceFromNib() as! MapMarkerWindow
infoWindow.remaingDriverTimelbl.pushTransition(0.4)
if self.estimatedITime != 0 && self.estimatedITime < 30*60 {
var inMinuts:Int = self.estimatedITime/60
if inMinuts == 0{
inMinuts = 1
};infoWindow.remaingDriverTimelbl.text = "\(inMinuts)"
} else { infoWindow.remaingDriverTimelbl.text = "~" }
self.sourceName = locationName
self.sourceAdress = locationAdress
mySrc.iconView = infoWindow
mySrc.zIndex = 1
infoWindow.sourceTitle.text = locationStringwithDetail
mySrc.position = sourceCoordinate
mySrc.map = self.mapView
There is no error. the issue is only on `iPhone X` device and simulator.
Here is screen shot for `iPhone 7+`:
Here is xib file

Getting Black Video on YouTube while Capturing Screen iOS

I am using this code to capture screen on iOS but while capturing browser which has YouTube Videos I get black Video
var view = UIApplication.SharedApplication.KeyWindow.RootViewController.View;
UIGraphics.BeginImageContext(view.Frame.Size);
view.DrawViewHierarchy(view.Frame, true);
var image = UIGraphics.GetImageFromCurrentImageContext();
UIGraphics.EndImageContext();
I tried this code to send the webview as a parameter to be captured the view refreshed and the webveiw show progress ring all the time and never reloaded:
public async Task<byte[]> CaptureAsync(Xamarin.Forms.View fView)
{
CGRect rect = new CGRect(fView.X, fView.Y, fView.Height, fView.Width);
var view = ConvertFormsToNative(fView, rect);
UIGraphics.BeginImageContext(view.Frame.Size);
view.DrawViewHierarchy(view.Frame, true);
var image = UIGraphics.GetImageFromCurrentImageContext();
UIGraphics.EndImageContext();
using (var imageData = image.AsPNG())
{
var bytes = new byte[imageData.Length];
System.Runtime.InteropServices.Marshal.Copy(imageData.Bytes, bytes, 0, Convert.ToInt32(imageData.Length));
return bytes;
}
}
private UIView ConvertFormsToNative(Xamarin.Forms.View view, CGRect size)
{
var renderer = RendererFactory.GetRenderer(view);
renderer.NativeView.Frame = size;
renderer.NativeView.AutoresizingMask = UIViewAutoresizing.All;
renderer.NativeView.ContentMode = UIViewContentMode.ScaleToFill;
renderer.Element.Layout(size.ToRectangle());
var nativeView = renderer.NativeView;
nativeView.SetNeedsLayout();
return nativeView;
}
It is because you captured the RootViewController.View not the webview or something else.
Just make sure that the view (which you want to convert to screenshot ) is the video view (WebView or WKWebvView or SFSafariViewController.view..)

Adding "SCNNode" to ScreenView to current view of the camera

I've got an image that im trying to add to the current camera location of the Screenview ARSCNView session. Whatever I do it seems to put the image behind the current location of the phone camera and i have to move it back to see it. I have the following code:
var currentFrame = SceneView.Session.CurrentFrame;
if (currentFrame == null) return;
var threeVector = new SCNVector3(currentFrame.Camera.Transform.Column3.X + 0.005f,
currentFrame.Camera.Transform.Column3.Y - 0.02f,
currentFrame.Camera.Transform.Column3.Z - 0.05f);
var scaleFactor = imgToAdd.Size.Width / 0.05;
float width = float.Parse((imgToAdd.Size.Width / scaleFactor).ToString());
float height = float.Parse((imgToAdd.Size.Height / scaleFactor).ToString());
var box = new SCNPlane {
Width = width,
Height = height
};
var cubeNode = new SCNNode {
Position = threeVector,
Geometry = box
};
var mat = new SCNMaterial();
mat.Diffuse.Contents = imgToAdd;
mat.LocksAmbientWithDiffuse = true;
cubeNode.Geometry.Materials = new[] { mat };
SceneView.Scene.RootNode.AddChildNode(cubeNode);
Just trying to execute a simple idea of the ARKit paint apps that you see all over the app store now. So the imgToAdd is a snapshot of the scribble that the user has already put onto the screen and this event is fired at the touchended after an image is created from the view scribbled on.
Any ideas on what I need to change to get it to line up with the current view of the camera on the phone?

UIDynamicAnimator interfering with addTarget and beginTouches?

I wish I had more reputation so I could attach a screenshot of what I'm working on but you can see an example in the second link down below.
Basically there is a middle button in the tab bar which brings out option buttons (apple images in this case).
These apple icons are animated to their positions using UIDynamicAnimator and UIAttachmentBehavior.
Here is the code which adds the option buttons
func showOptions() {
var numberOfItems = self.delegate.brOptionsButtonNumberOfItems(self)
//NSAssert(numberOfItems > 0 , "number of items should be more than 0")
var angle = 0.0
var radius:Int = 20 * numberOfItems
angle = (180.0 / Double(numberOfItems))
// convert to radians
angle = angle/180.0 * M_PI
for(var i = 0; i<numberOfItems; i++) {
var csCalc = Float((angle * Double(i)) + (angle/2))
var buttonX = Float(radius) * cosf(csCalc)
var buttonY = Float(radius) * sinf(csCalc)
var wut = (angle * Double(i)) + (angle/2)
var brOptionItem = self.createButtonItemAtIndex(i)
var mypoint = self.tabBar.convertPoint(self.center, fromView:self.superview)
var x = mypoint.x + CGFloat(buttonX)
var y = self.frame.origin.y - CGFloat(buttonY)
var buttonPoint = CGPointMake(x, y)
//println("Button Point of Button Item x:\(x) y: \(y)")
brOptionItem.layer.anchorPoint = self.layer.anchorPoint
brOptionItem.center = mypoint
var attachment = UIAttachmentBehavior(item:brOptionItem, attachedToAnchor:buttonPoint)
attachment.damping = self.damping
attachment.frequency = self.frequency
attachment.length = 1
// set the attachment for dragging behavior
brOptionItem.attachment = attachment
self.dynamicItem!.addItem(brOptionItem)
//if(self.delegate.respondsToSelector("willDisplayButtonItem")) { //Fix me
//self.delegate.brOptionsButton(self, willDisplayButtonItem:brOptionItem)
//}
self.tabBar.insertSubview(brOptionItem, belowSubview: self.tabBar)
self.dynamicsAnimator!.addBehavior(attachment)
self.items.addObject(brOptionItem)
}
}
func createButtonItemAtIndex(indexz:NSInteger) -> BROptionsItem {
println("Create button item at index")
var brOptionItem = BROptionsItem(initWithIndex:indexz)
brOptionItem.addTarget(self, action:"buttonItemPressed:", forControlEvents:.TouchUpInside)
brOptionItem.autoresizingMask = UIViewAutoresizing.None
var image = self.delegate.brOptionsButton(self, imageForItemAtIndex:indexz)
//if((image) != nil) {
brOptionItem.setImage(image, forState: UIControlState.Normal)
//}
/*
var buttonTitle = self.delegate.brOptionsButton(self, titleForItemAtIndex:indexz)
if(buttonTitle.utf16Count > 0) {
brOptionItem.setTitle(buttonTitle, forState:UIControlState.Normal)
}
*/
return brOptionItem;
}
In showOptions the animator is assigned an attachment behavior for a brOptionItem that was just created when createButtomItemAtIndex was called.
In createButtonItemAtIndex, the brOptionItem is created and a target was added to execute a function when the button was tapped.
The option buttons work without the animation. I can click them and the target function is executed.
However, when the animation is added and the option buttons are placed where they are, nothing happens when the buttons are tapped.
I am extremely stuck on this. I have no idea why the animation stops the tapping actions. The buttons are supposed to be draggable as well.
Here is my source code. The code I reference can be see in the BROptiosnButton file.
https://github.com/WobbleDev/BROptionsSwift
Here is the reference code I used
https://github.com/BasheerSience/BROptionsButton
Thanks!

Axes, labels, and titles are hidden or overlapped/occluded by the plot when the dataSource is updated

I'm using Core Plot successfully in an Objective-C app. I'm writing a new app in Swift and I'm having some trouble. Before I set a dataSource for my graph, the axes appear correctly and as expected. See the following screenshot:
Screenshot With Correct Axes
The problem is that when I set a dataSource, the data is rendered properly, but the axes disappear. See the following screenshot:
Screenshot With Axes Gone
I want the axes, labels, and titles to remain visible when the data is rendered. There are lots of possible causes, and I've tried to rule out all the ones I can think of. Here's what I've tried:
The problem isn't the axis title positions or graph padding, because they show up correctly at first.
I read one post saying graph.plotAreaFrame.masksToBorder = false should work. That didn't do it.
I tried setting the graph and plot area fills to nil to try to reveal the titles if they were occluded by the fill. A view behind the graph was revealed, but not the titles.
I tried various values for graph.topDownLayerOrder, trying to ensure the titles were the topmost item, esp. on top of the plot area. Note the docs say the default is axis titles on top, so I didn't expect this to fix it.
I confirmed with the debugger that the axis labels were not set as hidden.
Thanks in advance for any help, and thank you Eric for sharing this sweet library with us!
Following is my source code:
class TemperatureGraph: CPTGraphHostingView, CPTPlotSpaceDelegate {
// Just needed to retain dataSource
var dataSource: CPTPlotDataSource?
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
func setupGraphWithSession(session: Session?) {
self.configureGraph()
self.configurePlot()
self.configureAxes()
if (session != nil)
{
self.configureDataSource(session!)
}
}
func configureGraph() {
let graph: CPTGraph = CPTXYGraph(frame: self.bounds)
graph.applyTheme(CPTTheme(named: kCPTSlateTheme))
graph.title = "Temperature History (°F)"
graph.paddingTop = 0.0;
graph.paddingBottom = 0.0;
graph.paddingLeft = 0.0;
graph.paddingRight = 0.0;
// graph.titleDisplacement = CGPoint(x: 0, y: 20)
graph.plotAreaFrame.paddingTop = 30.0;
graph.plotAreaFrame.paddingBottom = 50.0;
graph.plotAreaFrame.paddingLeft = 50.0;
graph.plotAreaFrame.paddingRight = 10.0;
// This doesn't help
// graph.fill = nil;
// graph.plotAreaFrame.fill = nil;
// This doesn't help
// graph.plotAreaFrame.masksToBorder = false
// This doesn't help either
//graph.topDownLayerOrder = [NSNumber(unsignedInt: CPTGraphLayerTypeAxisTitles.value)]
// Some themes have a rounded border around the plot area. It looks bad since we removed the insets, so remove the border too.
graph.plotAreaFrame.borderLineStyle = nil;
graph.plotAreaFrame.cornerRadius = 0;
self.hostedGraph = graph
}
func configurePlot() {
let graph = self.hostedGraph
var plot = CPTScatterPlot()
// Make the data source line use curved interpolation
// plot.interpolation = CPTScatterPlotInterpolationCurved;
var lineStyle: CPTMutableLineStyle = plot.dataLineStyle.mutableCopy() as CPTMutableLineStyle
lineStyle.lineWidth = 1.0;
lineStyle.lineColor = CPTColor.redColor()
plot.dataLineStyle = lineStyle;
// For some reason, areaBaseValue isn't visible in swift. It's in the header and in Objective-C, don't know why it's not seen here.
//plot.areaFill = CPTFill(color: lineStyle.lineColor.colorWithAlphaComponent(0.2))
//plot.areaBaseValue = NSDecimalNumber.zero()
graph.addPlot(plot)
}
func configureAxes() {
let graph = self.hostedGraph
let plot = graph.plotAtIndex(0)
// The timestamps are large, which would make an inordinant number of axis label text by default, so to even render the graph in under a minute, simplify the axes.
var axisSet: CPTAxisSet = graph.axisSet
var axisTitleStyle = CPTMutableTextStyle()
axisTitleStyle.color = CPTColor.blackColor()
axisTitleStyle.fontName = "Helvetica-Bold"
axisTitleStyle.fontSize = 12
var xAxis = axisSet.axisForCoordinate(CPTCoordinateX, atIndex: 0)
xAxis.labelingPolicy = CPTAxisLabelingPolicyNone
xAxis.title = "Time"
xAxis.titleOffset = 15
xAxis.titleTextStyle = axisTitleStyle
var yAxis = axisSet.axisForCoordinate(CPTCoordinateY, atIndex: 0)
// yAxis.labelingPolicy = CPTAxisLabelingPolicyNone
yAxis.title = "Temperature (°F)"
yAxis.titleOffset = 25
yAxis.titleTextStyle = axisTitleStyle
}
func configureDataSource(sesh: Session) {
self.dataSource = TemperatureDatasource(session: sesh)
let plot = self.hostedGraph.plotAtIndex(0)
plot.dataSource = self.dataSource
plot.plotSpace.scaleToFitPlots([plot])
plot.plotSpace.allowsUserInteraction = true
plot.plotSpace.delegate = self
}
func plotSpace(space: CPTPlotSpace!, shouldScaleBy interactionScale: CGFloat, aboutPoint interactionPoint: CGPoint) -> Bool {
return true
}
func plotSpace(space: CPTPlotSpace!, willChangePlotRangeTo newRange: CPTPlotRange!, forCoordinate coordinate: CPTCoordinate) -> CPTPlotRange! {
// Adjust axis to keep them in view at the left and bottom;
// adjust scale-labels to match the scroll.
var allowedRange = newRange
if (coordinate.value == CPTCoordinateY.value) {
let space = self.hostedGraph.defaultPlotSpace as CPTXYPlotSpace
allowedRange = space.yRange
}
return allowedRange;
}
}
By default the axes always cross at (0, 0). I suspect your plot data doesn't cover that point, so scaleToFitPlots pushes (0, 0) outside the visible plot area and hides the axes. You have several options:
Use axisConstraints to lock the axes to a certain spot (e.g., the left edge of the plot area for the y-axis).
After calling scaleToFitPlots, update the orthogonalPosition of each axis within the corresponding plot range.
After calling scaleToFitPlots, expand the plot ranges so they include zero (0), if needed.

Resources