mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Location view fixes
This commit is contained in:
parent
28e2c78c81
commit
24e18d6f7a
@ -59,6 +59,7 @@ public final class DeviceLocationManager: NSObject {
|
|||||||
self.manager.distanceFilter = 5.0
|
self.manager.distanceFilter = 5.0
|
||||||
self.manager.activityType = .other
|
self.manager.activityType = .other
|
||||||
self.manager.pausesLocationUpdatesAutomatically = false
|
self.manager.pausesLocationUpdatesAutomatically = false
|
||||||
|
self.manager.headingFilter = 2.0
|
||||||
}
|
}
|
||||||
|
|
||||||
public func push(mode: DeviceLocationMode, updated: @escaping (CLLocation, Double?) -> Void) -> Disposable {
|
public func push(mode: DeviceLocationMode, updated: @escaping (CLLocation, Double?) -> Void) -> Disposable {
|
||||||
|
@ -147,12 +147,17 @@ public final class ChatMessageLiveLocationPositionNode: ASDisplayNode {
|
|||||||
var hasPulse = false
|
var hasPulse = false
|
||||||
var heading: Double?
|
var heading: Double?
|
||||||
var coordinate: (Double, Double)?
|
var coordinate: (Double, Double)?
|
||||||
|
|
||||||
|
func degToRad(_ degrees: Double) -> Double {
|
||||||
|
return degrees * Double.pi / 180.0
|
||||||
|
}
|
||||||
|
|
||||||
switch mode {
|
switch mode {
|
||||||
case let .liveLocation(_, active, latitude, longitude, headingValue):
|
case let .liveLocation(_, active, latitude, longitude, headingValue):
|
||||||
backgroundImage = avatarBackgroundImage
|
backgroundImage = avatarBackgroundImage
|
||||||
hasPulse = active
|
hasPulse = active
|
||||||
coordinate = (latitude, longitude)
|
coordinate = (latitude, longitude)
|
||||||
heading = headingValue.flatMap { Double($0) }
|
heading = headingValue.flatMap { degToRad(Double($0)) }
|
||||||
case let .location(location):
|
case let .location(location):
|
||||||
let venueType = location?.venue?.type ?? ""
|
let venueType = location?.venue?.type ?? ""
|
||||||
let color = venueType.isEmpty ? theme.list.itemAccentColor : venueIconColor(type: venueType)
|
let color = venueType.isEmpty ? theme.list.itemAccentColor : venueIconColor(type: venueType)
|
||||||
@ -162,10 +167,6 @@ public final class ChatMessageLiveLocationPositionNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func degToRad(_ degrees: Double) -> Double {
|
|
||||||
return degrees * Double.pi / 180.0
|
|
||||||
}
|
|
||||||
|
|
||||||
if heading == nil, let currentCoordinate = currentCoordinate, let coordinate = coordinate {
|
if heading == nil, let currentCoordinate = currentCoordinate, let coordinate = coordinate {
|
||||||
let lat1 = degToRad(currentCoordinate.0)
|
let lat1 = degToRad(currentCoordinate.0)
|
||||||
let lon1 = degToRad(currentCoordinate.1)
|
let lon1 = degToRad(currentCoordinate.1)
|
||||||
@ -248,7 +249,7 @@ public final class ChatMessageLiveLocationPositionNode: ASDisplayNode {
|
|||||||
strongSelf.arrowNode.isHidden = heading == nil || !hasPulse
|
strongSelf.arrowNode.isHidden = heading == nil || !hasPulse
|
||||||
strongSelf.arrowNode.position = CGPoint(x: 31.0, y: 64.0)
|
strongSelf.arrowNode.position = CGPoint(x: 31.0, y: 64.0)
|
||||||
|
|
||||||
strongSelf.arrowNode.transform = CATransform3DMakeRotation(CGFloat(heading ?? 0.0 / 180.0 * Double.pi), 0.0, 0.0, 1.0)
|
strongSelf.arrowNode.transform = CATransform3DMakeRotation(CGFloat(heading ?? 0), 0.0, 0.0, 1.0)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ class LocationPinAnnotation: NSObject, MKAnnotation {
|
|||||||
let peer: Peer?
|
let peer: Peer?
|
||||||
let message: Message?
|
let message: Message?
|
||||||
let forcedSelection: Bool
|
let forcedSelection: Bool
|
||||||
var heading: Int32? {
|
@objc dynamic var heading: NSNumber? {
|
||||||
willSet {
|
willSet {
|
||||||
self.willChangeValue(forKey: "heading")
|
self.willChangeValue(forKey: "heading")
|
||||||
}
|
}
|
||||||
@ -91,7 +91,7 @@ class LocationPinAnnotation: NSObject, MKAnnotation {
|
|||||||
}
|
}
|
||||||
self.selfPeer = selfPeer
|
self.selfPeer = selfPeer
|
||||||
self.forcedSelection = false
|
self.forcedSelection = false
|
||||||
self.heading = heading
|
self.heading = heading.flatMap { NSNumber(value: $0) }
|
||||||
super.init()
|
super.init()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,6 +167,8 @@ class LocationPinAnnotationView: MKAnnotationView {
|
|||||||
|
|
||||||
var hasPulse = false
|
var hasPulse = false
|
||||||
|
|
||||||
|
var headingKvoToken: NSKeyValueObservation?
|
||||||
|
|
||||||
override class var layerClass: AnyClass {
|
override class var layerClass: AnyClass {
|
||||||
return LocationPinAnnotationLayer.self
|
return LocationPinAnnotationLayer.self
|
||||||
}
|
}
|
||||||
@ -233,6 +235,14 @@ class LocationPinAnnotationView: MKAnnotationView {
|
|||||||
self.annotation = annotation
|
self.annotation = annotation
|
||||||
}
|
}
|
||||||
|
|
||||||
|
required init?(coder aDecoder: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
deinit {
|
||||||
|
self.headingKvoToken?.invalidate()
|
||||||
|
}
|
||||||
|
|
||||||
var defaultZPosition: CGFloat {
|
var defaultZPosition: CGFloat {
|
||||||
if let annotation = self.annotation as? LocationPinAnnotation {
|
if let annotation = self.annotation as? LocationPinAnnotation {
|
||||||
if annotation.forcedSelection {
|
if annotation.forcedSelection {
|
||||||
@ -247,10 +257,6 @@ class LocationPinAnnotationView: MKAnnotationView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
required init?(coder aDecoder: NSCoder) {
|
|
||||||
fatalError("init(coder:) has not been implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
override var annotation: MKAnnotation? {
|
override var annotation: MKAnnotation? {
|
||||||
didSet {
|
didSet {
|
||||||
if let annotation = self.annotation as? LocationPinAnnotation {
|
if let annotation = self.annotation as? LocationPinAnnotation {
|
||||||
@ -270,6 +276,18 @@ class LocationPinAnnotationView: MKAnnotationView {
|
|||||||
self.shadowNode.isHidden = true
|
self.shadowNode.isHidden = true
|
||||||
self.smallNode.isHidden = false
|
self.smallNode.isHidden = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let headingKvoToken = self.headingKvoToken {
|
||||||
|
self.headingKvoToken = nil
|
||||||
|
headingKvoToken.invalidate()
|
||||||
|
}
|
||||||
|
|
||||||
|
self.headingKvoToken = annotation.observe(\.heading, options: .new) { [weak self] (_, change) in
|
||||||
|
guard let heading = change.newValue else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self?.updateHeading(heading)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if let peer = annotation.peer {
|
else if let peer = annotation.peer {
|
||||||
self.iconNode.isHidden = true
|
self.iconNode.isHidden = true
|
||||||
@ -278,6 +296,12 @@ class LocationPinAnnotationView: MKAnnotationView {
|
|||||||
|
|
||||||
self.setPeer(context: annotation.context, theme: annotation.theme, peer: peer)
|
self.setPeer(context: annotation.context, theme: annotation.theme, peer: peer)
|
||||||
self.setSelected(true, animated: false)
|
self.setSelected(true, animated: false)
|
||||||
|
|
||||||
|
if let headingKvoToken = self.headingKvoToken {
|
||||||
|
self.headingKvoToken = nil
|
||||||
|
headingKvoToken.invalidate()
|
||||||
|
}
|
||||||
|
self.updateHeading(nil)
|
||||||
} else if let location = annotation.location {
|
} else if let location = annotation.location {
|
||||||
let venueType = location.venue?.type ?? ""
|
let venueType = location.venue?.type ?? ""
|
||||||
let color = venueType.isEmpty ? annotation.theme.list.itemAccentColor : venueIconColor(type: venueType)
|
let color = venueType.isEmpty ? annotation.theme.list.itemAccentColor : venueIconColor(type: venueType)
|
||||||
@ -299,15 +323,36 @@ class LocationPinAnnotationView: MKAnnotationView {
|
|||||||
self.setSelected(true, animated: false)
|
self.setSelected(true, animated: false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let avatarNode = self.avatarNode {
|
||||||
|
self.avatarNode = nil
|
||||||
|
avatarNode.removeFromSupernode()
|
||||||
|
}
|
||||||
|
|
||||||
if self.initialized && !self.appeared {
|
if self.initialized && !self.appeared {
|
||||||
self.appeared = true
|
self.appeared = true
|
||||||
self.animateAppearance()
|
self.animateAppearance()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let headingKvoToken = self.headingKvoToken {
|
||||||
|
self.headingKvoToken = nil
|
||||||
|
headingKvoToken.invalidate()
|
||||||
|
}
|
||||||
|
self.updateHeading(nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func updateHeading(_ heading: NSNumber?) {
|
||||||
|
if let heading = heading?.int32Value {
|
||||||
|
self.arrowNode.isHidden = false
|
||||||
|
self.arrowNode.transform = CATransform3DMakeRotation(CGFloat(heading) / 180.0 * CGFloat.pi, 0.0, 0.0, 1.0)
|
||||||
|
} else {
|
||||||
|
self.arrowNode.isHidden = true
|
||||||
|
self.arrowNode.transform = CATransform3DIdentity
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override func prepareForReuse() {
|
override func prepareForReuse() {
|
||||||
self.smallNode.isHidden = true
|
self.smallNode.isHidden = true
|
||||||
self.backgroundNode.isHidden = false
|
self.backgroundNode.isHidden = false
|
||||||
|
@ -372,6 +372,11 @@ final class LocationMapNode: ASDisplayNode, MKMapViewDelegate {
|
|||||||
var trackingMode: LocationTrackingMode = .none {
|
var trackingMode: LocationTrackingMode = .none {
|
||||||
didSet {
|
didSet {
|
||||||
self.mapView?.userTrackingMode = self.trackingMode.userTrackingMode
|
self.mapView?.userTrackingMode = self.trackingMode.userTrackingMode
|
||||||
|
if self.trackingMode == .followWithHeading && self.headingArrowView?.image != nil {
|
||||||
|
self.headingArrowView?.image = nil
|
||||||
|
} else if self.trackingMode != .followWithHeading && self.headingArrowView?.image == nil {
|
||||||
|
self.headingArrowView?.image = generateHeadingArrowImage()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -676,9 +681,45 @@ final class LocationMapNode: ASDisplayNode, MKMapViewDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let updatedAnnotation = dict[annotation.id] {
|
if let updatedAnnotation = dict[annotation.id] {
|
||||||
|
func degToRad(_ degrees: Double) -> Double {
|
||||||
|
return degrees * Double.pi / 180.0
|
||||||
|
}
|
||||||
|
|
||||||
|
func radToDeg(_ radians: Double) -> Double {
|
||||||
|
return radians / Double.pi * 180.0
|
||||||
|
}
|
||||||
|
|
||||||
|
let currentCoordinate = annotation.coordinate
|
||||||
|
let coordinate = updatedAnnotation.coordinate
|
||||||
|
var heading = updatedAnnotation.heading
|
||||||
|
if heading == nil {
|
||||||
|
let previous = CLLocation(latitude: currentCoordinate.latitude, longitude: currentCoordinate.longitude)
|
||||||
|
let new = CLLocation(latitude: coordinate.latitude, longitude: coordinate.longitude)
|
||||||
|
|
||||||
|
if new.distance(from: previous) > 10 {
|
||||||
|
let lat1 = degToRad(currentCoordinate.latitude)
|
||||||
|
let lon1 = degToRad(currentCoordinate.longitude)
|
||||||
|
let lat2 = degToRad(coordinate.latitude)
|
||||||
|
let lon2 = degToRad(coordinate.longitude)
|
||||||
|
|
||||||
|
let dLat = lat2 - lat1
|
||||||
|
let dLon = lon2 - lon1
|
||||||
|
|
||||||
|
if dLat != 0 && dLon != 0 {
|
||||||
|
let y = sin(dLon) * cos(lat2)
|
||||||
|
let x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(dLon)
|
||||||
|
heading = NSNumber(value: radToDeg(atan2(y, x)))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
heading = annotation.heading
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
UIView.animate(withDuration: 0.2) {
|
UIView.animate(withDuration: 0.2) {
|
||||||
annotation.coordinate = updatedAnnotation.coordinate
|
annotation.coordinate = updatedAnnotation.coordinate
|
||||||
}
|
}
|
||||||
|
|
||||||
|
annotation.heading = heading
|
||||||
dict[annotation.id] = nil
|
dict[annotation.id] = nil
|
||||||
} else {
|
} else {
|
||||||
annotationsToRemove.insert(annotation)
|
annotationsToRemove.insert(annotation)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user