How to change default camera behavior when marker is tapped? - google-maps-markers

In release 1.2 of the Google Maps for iOS SDK the default behavior of a tapped marker changed.
The release note says: "The default behavior when a marker is tapped has been updated to also pan the camera to the marker's position"
How can I get the old behavior back, i.e. not panning the camera center to the position of the marker?

Add the following method to your GMSMapView delegate implementation. GMSMapView will no longer center on the selected marker and brings back the existing behavior.
- (BOOL) mapView:(GMSMapView *)mapView didTapMarker:(GMSMarker *)marker {
mapView.selectedMarker = marker;
return TRUE;
}

you can use this:
mapView.selectedMarker = nil
func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool {
mapView.selectedMarker = nil
return true
}

Related

Weird rectangle (NSBannerView) in left top of NSTableView

I'm working on an macOS app and I'm experiencing a weird issue. In the left top corner of my NSTableView (above the header), a grey rectangle is shown:
(I've added an NSBox behind the NSTableView to make it more clear in the screenshot)
With the Debug View Hierarchy, I've seen it's an NSBannerView which is added to the Scroll View wrapping the Table View.
My UI is built with Interface Builder (a storyboard). I've checked and unchecked lots of checkboxes in the Interface Builder but can't find what it is. Google and Stack Overflow also don't give any clues. Googling for "NSBannerView" even only yields some macOS header files.
How to get rid of the rectangle?
Environment details
macOS Mojave 10.14 Beta (18A365a)
Xcode 9.4.1 (9F2000)
Subclass NSTableRowView and overwrite layout, where you hide the view
- (void)layout {
[super layout];
for (NSView * v in self.subviews) {
if ([v.className isEqual:#"NSBannerView"]) {
v.hidden = YES;
}
}
}
Making this hiding thing into didAddSubview might be a better solution like the example below. Because layout is called each time you select the row.
override func didAddSubview(_ subview: NSView) {
super.didAddSubview(subview)
if subview.className == "NSBannerView" {
subview.isHidden = true
}
}
I use currently use this to correct a ugly looking NSBannerView:
func tableView(_ tableView: NSTableView, didAdd rowView: NSTableRowView, forRow row: Int) {
if rowView.isGroupRowStyle {
for view in rowView.subviews {
if let effect = view.subviews.first as? NSVisualEffectView {
effect.material = .contentBackground // Or something else, the default material for group headers is .headerView
}
}
}
}

SpriteKit Xcode level editor no touch events on custom button class (3d touch)

I am having trouble getting custom SKSpriteNode buttons to work with the xCode level editor on devices with 3d Touch.
I have a button subclass which is mostly based on the DemoBots sample from apple.
The basic code would be this
enum ButtonIdentifier: String {
case playButton
case pauseButton
}
/// Button responder delegate
protocol ButtonDelegate: class {
func pressed(button button: ButtonNode)
}
class ButtonNode: SKSpriteNode {
public weak var delegate: ButtonDelegate? {
return scene as? ButtonDelegate
}
var isHighlighted = false {
didSet {
// running skactions to colorise buttons and animate
}
}
var identifier: ButtonIdentifier!
/// Code init (when button is created in code)
/// e.g let playButton = ButtonNode(imageNamed: "ButtonImage", identifier: playButton)
init(imageNamed: String, identifier: ButtonIdentifier) {
self.identifier = identifier
let texture = SKTexture(imageNamed: imageNamed)
super.init(texture: texture, color: SKColor.clearColor(), size: texture.size())
name = identifier.rawValue
setup()
}
/// Level editor init (when button is created in level editor)
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
// Ensure that the node has a supported button identifier as its name.
guard let nodeName = name, identifier = ButtonIdentifier(rawValue: nodeName) else {
fatalError("Unsupported button name found.")
}
self.identifier = identifier
setup()
}
private func setup() {
// zPosition
zPosition = 200
// Enable user interaction on the button node to detect tap and click events.
userInteractionEnabled = true
}
#if os(iOS)
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
super.touchesBegan(touches, withEvent: event)
isHighlighted = true
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
super.touchesEnded(touches, withEvent: event)
guard let scene = scene else { return }
for touch in touches {
let location = touch.locationInNode(scene)
let node = scene.nodeAtPoint(location)
if node === self || node.inParentHierarchy(self) {
runPressedAction()
} else {
isHighlighted = false
}
}
}
override func touchesCancelled(touches: Set<UITouch>?, withEvent event: UIEvent?) {
super.touchesCancelled(touches, withEvent: event)
isHighlighted = false
}
#endif
// MARK: - Pressed Action
private func runPressedAction() {
// SKAction that runs a press animation
delegate?.pressed(button: self)
}
}
If i create the button via the xCode level editor everything is working fine in the simulator or on my iPhone 6, however when using test flight my friend with a 6s Plus gets no touch input on the buttons, he cannot press them.
If I create the button all in code everything works, even on 3d touch devices.
Why is it not working with buttons from the level editor on 3d touch devices? I have been trying to look at apples demo bots sample to see if I missed some setting or something, but I cannot figure it out. (Demo bots buttons do work on my friends iPhone 6s plus)
I know that on 3d touch devices touchesMoved method gets called even though there are no changes in the x/y coordinates. However I don't think this causes my issues because when creating buttons in code everything is working as expected.
Is there some setting in the Xcode level editor I am missing to allow touches on 3d touch devices?
After days of frustration it turned out it was a iOS 9 bug. My friend was on iOS 9.2.x and after he updated to the latest iOS 9.3.x version everything is working, no code changes where required at all.

Why my UITextView text is not show from starting and hide under Navigation Bar

I wonder why my textview text didn't show up from starting text.
This is the image from my Xcode IB
When I run it on my iPhone 6 Simulator and others
Actually it should start from "Example Notification...."
Please help me out.
Those who didn't start UITextView from start,here is the answer.I am sure it worked 100% on iOS 8 and higher on any devices.
1.You need to deselect these at your view controller where textview is applied
Go to ViewController > Attribute Inspector > Search Extend Edges > Under Top Bars & Under Button Bars
2.Add the following code at your view controller
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
self.yourTextView.setContentOffset(CGPoint.zero, animated: false)
}
Special Thanks to #El Captain
To maintain UINavigationBar translucent and allow user to rotate the device while reading UITextView I used something like this:
private var firstLayout = true
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
if firstLayout {
firstLayout = false
textView.setContentOffset(
CGPoint(x: 0, y: -topLayoutGuide.length), animated: false)
}
}
Tested on iOS 9 and iOS 12 Beta.
In my case it was iOS 13. UITextView was constrained to edges. It's content was set on did load, after that text view automatically scrolled to the bottom causing large title to shrink.
What helped me is to wrap setText in to async:
DispatchQueue.main.async {
textView.text = logs
}
You can also keep UINavigationBar isTranslucent and UIScrollViewContentInsetAdjustmentAutomatic,
Just to fix the textView is hidden by navigationBar, then add the below code:
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
[textView setContentOffset:CGPointMake(0, -self.view.layoutMargins.top) animated:NO];
}

How to zoom into pin in MKMapView Swift

I want the location of the pin to zoom in on tapping the pin so that the location is at the center. I have no idea how to do this. Please help me.
There's a couple of things you are trying to make happen.
Figuring out which pin was tapped
Centering the mapView on the tapped pin
If you have the mapView properly initiated in your project (with the view as its delegate), then both of the above points can be done by using the mapView(_:didSelectAnnotationView:) method, like this:
func mapView(mapView: MKMapView, didSelectAnnotationView view: MKAnnotationView) {
// get the particular pin that was tapped
let pinToZoomOn = view.annotation
// optionally you can set your own boundaries of the zoom
let span = MKCoordinateSpanMake(0.5, 0.5)
// or use the current map zoom and just center the map
// let span = mapView.region.span
// now move the map
let region = MKCoordinateRegion(center: pinToZoomOn!.coordinate, span: span)
mapView.setRegion(region, animated: true)
}
This method tells the delegate (your view most probably) that one of the map annotation views was selected and to move (and or zoom) to that coordinate area.

Getting Mouse Coordinates in Swift

Swift newbie here.
I've been having trouble with a task that should be trivial. All I want to do is get the x,y coordinates of the mouse cursor on-demand. I would prefer not to wait for a mouse movement event to fire before I can grab the pointer's coords.
Would appreciate any help!
You should take a look at NSEvent method mouseLocation
edit/update: Xcode 11 • Swift 5.1
If you would like to monitor events on any window when your app is active, you can add a LocalMonitorForEvents matching mouseMoved mask and if it is not active a GlobalMonitorForEvents. Note that you need set to your window property acceptsMouseMovedEvents to true
import Cocoa
class ViewController: NSViewController {
lazy var window: NSWindow = self.view.window!
var mouseLocation: NSPoint { NSEvent.mouseLocation }
var location: NSPoint { window.mouseLocationOutsideOfEventStream }
override func viewDidLoad() {
super.viewDidLoad()
NSEvent.addLocalMonitorForEvents(matching: [.mouseMoved]) {
print("mouseLocation:", String(format: "%.1f, %.1f", self.mouseLocation.x, self.mouseLocation.y))
print("windowLocation:", String(format: "%.1f, %.1f", self.location.x, self.location.y))
return $0
}
NSEvent.addGlobalMonitorForEvents(matching: [.mouseMoved]) { _ in
print(String(format: "%.0f, %.0f", self.mouseLocation.x, self.mouseLocation.y))
}
}
override func viewWillAppear() {
super.viewWillAppear()
window.acceptsMouseMovedEvents = true
}
}
Sample project
You can get the current mouse location in this way:
Declare this in your view controller class:
var mouseLocation: NSPoint? { self.view.window?.mouseLocationOutsideOfEventStream }
Then, you can get the current mouse location and convert in your desired view coordinates:
if let currentMouseLocation = self.mouseLocation{
let pointInTargetView = self.**targetView**.convert(currentMouseLocation, from: self.view)
}

Resources