Location picker fixes

This commit is contained in:
Ilya Laktyushin 2019-11-26 13:10:38 +04:00
parent 06f3b42cde
commit 3b931cfd96
8 changed files with 2699 additions and 2426 deletions

View File

@ -5145,3 +5145,4 @@ Any member of this group will be able to see messages in the channel.";
"AuthSessions.AddDevice" = "Add Device";
"Map.SendThisPlace" = "Send This Place";
"Map.SetThisPlace" = "Set This Place";

View File

@ -79,7 +79,7 @@ private func generateLiveLocationIcon(theme: PresentationTheme) -> UIImage {
}!
}
public class LocationActionListItem: ListViewItem {
final class LocationActionListItem: ListViewItem {
let presentationData: ItemListPresentationData
let account: Account
let title: String
@ -136,7 +136,7 @@ public class LocationActionListItem: ListViewItem {
}
}
class LocationActionListItemNode: ListViewItemNode {
final class LocationActionListItemNode: ListViewItemNode {
private let backgroundNode: ASDisplayNode
private let separatorNode: ASDisplayNode
private let highlightedBackgroundNode: ASDisplayNode

View File

@ -2,6 +2,7 @@ import Foundation
import UIKit
import MapKit
import Display
import SwiftSignalKit
import Postbox
import SyncCore
import TelegramCore
@ -30,14 +31,26 @@ class LocationPinAnnotation: NSObject, MKAnnotation {
let account: Account
let theme: PresentationTheme
var coordinate: CLLocationCoordinate2D
let location: TelegramMediaMap
let location: TelegramMediaMap?
let peer: Peer?
var title: String? = ""
var subtitle: String? = ""
init(account: Account, theme: PresentationTheme, peer: Peer) {
self.account = account
self.theme = theme
self.location = nil
self.peer = peer
self.coordinate = kCLLocationCoordinate2DInvalid
super.init()
}
init(account: Account, theme: PresentationTheme, location: TelegramMediaMap) {
self.account = account
self.theme = theme
self.location = location
self.peer = nil
self.coordinate = location.coordinate
super.init()
}
@ -133,20 +146,29 @@ class LocationPinAnnotationView: MKAnnotationView {
override var annotation: MKAnnotation? {
didSet {
if let annotation = self.annotation as? LocationPinAnnotation {
let venueType = annotation.location.venue?.type ?? ""
let color = venueType.isEmpty ? annotation.theme.list.itemAccentColor : venueIconColor(type: venueType)
self.backgroundNode.image = generateTintedImage(image: UIImage(bundleImageName: "Location/PinBackground"), color: color)
self.iconNode.setSignal(venueIcon(postbox: annotation.account.postbox, type: annotation.location.venue?.type ?? "", background: false))
self.smallIconNode.setSignal(venueIcon(postbox: annotation.account.postbox, type: annotation.location.venue?.type ?? "", background: false))
self.smallNode.image = generateSmallBackgroundImage(color: color)
self.dotNode.image = generateFilledCircleImage(diameter: 6.0, color: color)
self.dotNode.isHidden = false
if !self.isSelected {
self.dotNode.alpha = 0.0
self.shadowNode.isHidden = true
self.smallNode.isHidden = false
if let peer = annotation.peer {
self.iconNode.isHidden = true
self.dotNode.isHidden = true
self.backgroundNode.image = UIImage(bundleImageName: "Location/PinBackground")
self.setPeer(account: annotation.account, theme: annotation.theme, peer: peer)
self.setSelected(true, animated: false)
} else if let location = annotation.location {
let venueType = annotation.location?.venue?.type ?? ""
let color = venueType.isEmpty ? annotation.theme.list.itemAccentColor : venueIconColor(type: venueType)
self.backgroundNode.image = generateTintedImage(image: UIImage(bundleImageName: "Location/PinBackground"), color: color)
self.iconNode.setSignal(venueIcon(postbox: annotation.account.postbox, type: venueType, background: false))
self.smallIconNode.setSignal(venueIcon(postbox: annotation.account.postbox, type: venueType, background: false))
self.smallNode.image = generateSmallBackgroundImage(color: color)
self.dotNode.image = generateFilledCircleImage(diameter: 6.0, color: color)
self.dotNode.isHidden = false
if !self.isSelected {
self.dotNode.alpha = 0.0
self.shadowNode.isHidden = true
self.smallNode.isHidden = false
}
}
}
}
@ -165,6 +187,17 @@ class LocationPinAnnotationView: MKAnnotationView {
self.animating = true
if selected {
let avatarSnapshot = self.avatarNode?.view.snapshotContentTree()
if let avatarSnapshot = avatarSnapshot, let avatarNode = self.avatarNode {
self.smallNode.view.addSubview(avatarSnapshot)
avatarSnapshot.layer.transform = avatarNode.transform
avatarSnapshot.center = CGPoint(x: self.smallNode.frame.width / 2.0, y: self.smallNode.frame.height / 2.0)
avatarNode.transform = CATransform3DIdentity
self.backgroundNode.addSubnode(avatarNode)
avatarNode.position = CGPoint(x: self.backgroundNode.frame.width / 2.0, y: self.backgroundNode.frame.height / 2.0 - 5.0)
}
self.shadowNode.position = CGPoint(x: self.shadowNode.position.x, y: self.shadowNode.position.y + self.shadowNode.frame.height / 2.0)
self.shadowNode.anchorPoint = CGPoint(x: 0.5, y: 1.0)
self.shadowNode.isHidden = false
@ -184,11 +217,27 @@ class LocationPinAnnotationView: MKAnnotationView {
self.smallNode.isHidden = true
self.smallNode.transform = CATransform3DIdentity
if let avatarNode = self.avatarNode {
self.addSubnode(avatarNode)
avatarSnapshot?.removeFromSuperview()
}
}
self.dotNode.alpha = 1.0
self.dotNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
} else {
let avatarSnapshot = self.avatarNode?.view.snapshotContentTree()
if let avatarSnapshot = avatarSnapshot, let avatarNode = self.avatarNode {
self.backgroundNode.view.addSubview(avatarSnapshot)
avatarSnapshot.layer.transform = avatarNode.transform
avatarSnapshot.center = CGPoint(x: self.backgroundNode.frame.width / 2.0, y: self.backgroundNode.frame.height / 2.0 - 5.0)
avatarNode.transform = CATransform3DMakeScale(0.64, 0.64, 1.0)
self.smallNode.addSubnode(avatarNode)
avatarNode.position = CGPoint(x: self.smallNode.frame.width / 2.0, y: self.smallNode.frame.height / 2.0)
}
self.smallNode.isHidden = false
self.smallNode.transform = CATransform3DMakeScale(0.01, 0.01, 1.0)
@ -209,6 +258,11 @@ class LocationPinAnnotationView: MKAnnotationView {
self.shadowNode.isHidden = true
self.shadowNode.transform = CATransform3DIdentity
if let avatarNode = self.avatarNode {
self.addSubnode(avatarNode)
avatarSnapshot?.removeFromSuperview()
}
}
let previousAlpha = self.dotNode.alpha
@ -249,6 +303,7 @@ class LocationPinAnnotationView: MKAnnotationView {
if let avatarNode = self.avatarNode {
avatarNode.position = self.isSelected ? CGPoint(x: UIScreenPixel, y: -41.0) : CGPoint()
avatarNode.transform = self.isSelected ? CATransform3DIdentity : CATransform3DMakeScale(0.64, 0.64, 1.0)
avatarNode.view.superview?.bringSubviewToFront(avatarNode.view)
}
if !self.appeared {
@ -277,9 +332,77 @@ class LocationPinAnnotationView: MKAnnotationView {
avatarNode.setPeer(account: account, theme: theme, peer: peer)
}
func setRaised(_ raised: Bool, avatar: Bool, animated: Bool, completion: @escaping () -> Void = {}) {
private var raised = false
func setRaised(_ raised: Bool, animated: Bool, completion: @escaping () -> Void = {}) {
guard raised != self.raised else {
return
}
self.raised = raised
self.shadowNode.layer.removeAllAnimations()
if animated {
if raised {
let previousPosition = self.shadowNode.position
self.shadowNode.layer.animatePosition(from: previousPosition, to: CGPoint(x: UIScreenPixel, y: -66.0), duration: 0.2, delay: 0.0, timingFunction: kCAMediaTimingFunctionSpring) { finished in
if finished {
completion()
}
}
} else {
UIView.animate(withDuration: 0.2, delay: 0.0, usingSpringWithDamping: 0.6, initialSpringVelocity: 0.0, options: [.allowAnimatedContent], animations: {
self.shadowNode.position = CGPoint(x: UIScreenPixel, y: -36.0)
}) { finished in
if finished {
completion()
}
}
}
} else {
self.shadowNode.position = CGPoint(x: UIScreenPixel, y: raised ? -66.0 : -36.0)
completion()
}
}
func setCustom(_ custom: Bool, animated: Bool) {
if animated {
self.animating = true
if let annotation = self.annotation as? LocationPinAnnotation {
self.iconNode.setSignal(venueIcon(postbox: annotation.account.postbox, type: "", background: false))
}
if let avatarNode = self.avatarNode {
self.backgroundNode.addSubnode(avatarNode)
avatarNode.position = CGPoint(x: self.backgroundNode.frame.width / 2.0, y: self.backgroundNode.frame.height / 2.0 - 5.0)
}
self.shadowNode.position = CGPoint(x: UIScreenPixel, y: -36.0)
self.backgroundNode.position = CGPoint(x: self.shadowNode.frame.width / 2.0, y: self.shadowNode.frame.height / 2.0)
self.iconNode.position = CGPoint(x: self.shadowNode.frame.width / 2.0, y: self.shadowNode.frame.height / 2.0 - 5.0)
Queue.mainQueue().after(0.01) {
UIView.transition(with: self.backgroundNode.view, duration: 0.2, options: [.transitionCrossDissolve, .allowAnimatedContent], animations: {
let color: UIColor
if custom, let annotation = self.annotation as? LocationPinAnnotation {
color = annotation.theme.list.itemAccentColor
} else {
color = .white
}
self.backgroundNode.image = generateTintedImage(image: UIImage(bundleImageName: "Location/PinBackground"), color: color)
self.avatarNode?.isHidden = custom
self.iconNode.isHidden = !custom
}) { finished in
if !custom, let avatarNode = self.avatarNode {
self.addSubnode(avatarNode)
}
self.animating = false
self.setNeedsLayout()
}
}
self.setNeedsLayout()
}
self.dotNode.isHidden = !custom
}
}

View File

@ -23,9 +23,20 @@ public enum LocationMapMode {
}
}
class LocationMapNode: ASDisplayNode, MKMapViewDelegate {
private class PickerAnnotationContainerView: UIView {
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
let result = super.hitTest(point, with: event)
if result == self {
return nil
}
return result
}
}
final class LocationMapNode: ASDisplayNode, MKMapViewDelegate {
private let locationPromise = Promise<CLLocation?>(nil)
private let pickerAnnotationContainerView: PickerAnnotationContainerView
private weak var userLocationAnnotationView: MKAnnotationView?
private var mapView: MKMapView? {
@ -33,12 +44,15 @@ class LocationMapNode: ASDisplayNode, MKMapViewDelegate {
}
var ignoreRegionChanges = false
var dragging = false
var isDragging = false
var beganInteractiveDragging: (() -> Void)?
var endedInteractiveDragging: ((CLLocationCoordinate2D) -> Void)?
var annotationSelected: ((LocationPinAnnotation?) -> Void)?
override init() {
self.pickerAnnotationContainerView = PickerAnnotationContainerView()
self.pickerAnnotationContainerView.isHidden = true
super.init()
self.setViewBlock({
@ -61,6 +75,8 @@ class LocationMapNode: ASDisplayNode, MKMapViewDelegate {
self.mapView?.isRotateEnabled = self.isRotateEnabled
self.mapView?.showsUserLocation = true
self.mapView?.showsPointsOfInterest = false
self.view.addSubview(self.pickerAnnotationContainerView)
}
var isRotateEnabled: Bool = true {
@ -75,7 +91,7 @@ class LocationMapNode: ASDisplayNode, MKMapViewDelegate {
}
}
func setMapCenter(coordinate: CLLocationCoordinate2D, span: MKCoordinateSpan = defaultMapSpan, offset: CGPoint = CGPoint(), animated: Bool = false) {
func setMapCenter(coordinate: CLLocationCoordinate2D, span: MKCoordinateSpan = defaultMapSpan, offset: CGPoint = CGPoint(), isUserLocation: Bool = false, animated: Bool = false) {
let region = MKCoordinateRegion(center: coordinate, span: span)
self.ignoreRegionChanges = true
if offset == CGPoint() {
@ -94,16 +110,23 @@ class LocationMapNode: ASDisplayNode, MKMapViewDelegate {
for gestureRecognizer in gestureRecognizers {
if gestureRecognizer.state == .began || gestureRecognizer.state == .ended {
self.dragging = true
self.isDragging = true
self.beganInteractiveDragging?()
if self.hasPickerAnnotation {
self.customUserLocationAnnotationView?.isHidden = true
self.pickerAnnotationContainerView.isHidden = false
self.pickerAnnotationView?.setCustom(true, animated: true)
self.resetAnnotationSelection()
}
break
}
}
}
func mapView(_ mapView: MKMapView, regionDidChangeAnimated animated: Bool) {
if self.dragging, let coordinate = self.mapCenterCoordinate {
self.dragging = false
if self.isDragging, let coordinate = self.mapCenterCoordinate {
self.isDragging = false
self.endedInteractiveDragging?(coordinate)
}
}
@ -140,6 +163,9 @@ class LocationMapNode: ASDisplayNode, MKMapViewDelegate {
for view in views {
if view.annotation is MKUserLocation {
self.userLocationAnnotationView = view
if let annotationView = self.customUserLocationAnnotationView {
view.addSubview(annotationView)
}
} else if let view = view as? LocationPinAnnotationView {
view.setZPosition(-1.0)
}
@ -156,16 +182,27 @@ class LocationMapNode: ASDisplayNode, MKMapViewDelegate {
}
self.annotationSelected?(annotation)
if let annotationView = self.customUserLocationAnnotationView, annotationView.isSelected {
annotationView.setSelected(false, animated: true)
}
}
func mapView(_ mapView: MKMapView, didDeselect view: MKAnnotationView) {
if let view = view as? LocationPinAnnotationView {
view.setZPosition(-1.0)
Queue.mainQueue().after(0.2) {
view.setZPosition(-1.0)
}
}
Queue.mainQueue().after(0.05) {
if mapView.selectedAnnotations.isEmpty {
self.annotationSelected?(nil)
if !self.isDragging {
self.annotationSelected?(nil)
}
if let annotationView = self.customUserLocationAnnotationView, !annotationView.isSelected {
annotationView.setSelected(true, animated: true)
}
}
}
}
@ -190,6 +227,39 @@ class LocationMapNode: ASDisplayNode, MKMapViewDelegate {
}
}
var pickerAnnotationView: LocationPinAnnotationView? = nil
var hasPickerAnnotation: Bool = false {
didSet {
if self.hasPickerAnnotation, let annotation = self.userLocationAnnotation {
let pickerAnnotationView = LocationPinAnnotationView(annotation: annotation)
pickerAnnotationView.center = CGPoint(x: self.pickerAnnotationContainerView.frame.width / 2.0, y: self.pickerAnnotationContainerView.frame.height / 2.0 + 16.0)
self.pickerAnnotationContainerView.addSubview(pickerAnnotationView)
self.pickerAnnotationView = pickerAnnotationView
} else {
self.pickerAnnotationView?.removeFromSuperview()
self.pickerAnnotationView = nil
}
}
}
var customUserLocationAnnotationView: LocationPinAnnotationView? = nil
var userLocationAnnotation: LocationPinAnnotation? = nil {
didSet {
if let annotation = self.userLocationAnnotation {
let annotationView = LocationPinAnnotationView(annotation: annotation)
annotationView.frame = annotationView.frame.offsetBy(dx: 21.0, dy: 22.0)
if let parentView = self.userLocationAnnotationView {
parentView.addSubview(annotationView)
}
self.customUserLocationAnnotationView = annotationView
self.pickerAnnotationView?.annotation = annotation
} else {
self.customUserLocationAnnotationView?.removeFromSuperview()
self.customUserLocationAnnotationView = nil
}
}
}
var annotations: [LocationPinAnnotation] = [] {
didSet {
@ -199,7 +269,7 @@ class LocationMapNode: ASDisplayNode, MKMapViewDelegate {
var dict: [String: LocationPinAnnotation] = [:]
for annotation in self.annotations {
if let identifier = annotation.location.venue?.id {
if let identifier = annotation.location?.venue?.id {
dict[identifier] = annotation
}
}
@ -210,7 +280,7 @@ class LocationMapNode: ASDisplayNode, MKMapViewDelegate {
continue
}
if let identifier = annotation.location.venue?.id, let updatedAnnotation = dict[identifier] {
if let identifier = annotation.location?.venue?.id, let updatedAnnotation = dict[identifier] {
annotation.coordinate = updatedAnnotation.coordinate
dict[identifier] = nil
} else {
@ -222,4 +292,13 @@ class LocationMapNode: ASDisplayNode, MKMapViewDelegate {
mapView.addAnnotations(Array(dict.values))
}
}
override func layout() {
super.layout()
self.pickerAnnotationContainerView.frame = CGRect(x: 0.0, y: floorToScreenPixels((self.frame.size.height - self.frame.size.width) / 2.0), width: self.frame.size.width, height: self.frame.size.width)
if let pickerAnnotationView = self.pickerAnnotationView {
pickerAnnotationView.center = CGPoint(x: self.pickerAnnotationContainerView.frame.width / 2.0, y: self.pickerAnnotationContainerView.frame.height / 2.0 + 16.0)
}
}
}

View File

@ -238,6 +238,8 @@ final class LocationPickerControllerNode: ViewControllerTracingNode {
private let listNode: ListView
private let headerNode: LocationMapHeaderNode
private let activityIndicator: ActivityIndicator
private let shadeNode: ASDisplayNode
private let innerShadeNode: ASDisplayNode
private let optionsNode: LocationOptionsNode
private(set) var searchContainerNode: LocationSearchContainerNode?
@ -274,6 +276,12 @@ final class LocationPickerControllerNode: ViewControllerTracingNode {
self.activityIndicator = ActivityIndicator(type: .custom(self.presentationData.theme.list.itemSecondaryTextColor, 22.0, 1.0, false))
self.shadeNode = ASDisplayNode()
self.shadeNode.backgroundColor = self.presentationData.theme.list.plainBackgroundColor
self.shadeNode.alpha = 0.0
self.innerShadeNode = ASDisplayNode()
self.innerShadeNode.backgroundColor = self.presentationData.theme.list.plainBackgroundColor
super.init()
self.backgroundColor = self.presentationData.theme.list.plainBackgroundColor
@ -282,6 +290,8 @@ final class LocationPickerControllerNode: ViewControllerTracingNode {
self.addSubnode(self.headerNode)
self.addSubnode(self.optionsNode)
self.listNode.addSubnode(self.activityIndicator)
self.shadeNode.addSubnode(self.innerShadeNode)
self.addSubnode(self.shadeNode)
let userLocation: Signal<CLLocation?, NoError> = self.headerNode.mapNode.userLocation
let filteredUserLocation: Signal<CLLocation?, NoError> = userLocation
@ -328,14 +338,34 @@ final class LocationPickerControllerNode: ViewControllerTracingNode {
|> deliverOnMainQueue).start(next: { [weak self] presentationData, state, userLocation, venues in
if let strongSelf = self {
var entries: [LocationPickerEntry] = []
switch state.selectedLocation {
case let .location(coordinate, address):
entries.append(.location(presentationData.theme, presentationData.strings.Map_SendThisLocation, address ?? presentationData.strings.Map_Locating, nil, coordinate))
let title: String
switch strongSelf.mode {
case .share:
title = presentationData.strings.Map_SendThisLocation
case .pick:
title = presentationData.strings.Map_SetThisLocation
}
entries.append(.location(presentationData.theme, title, address ?? presentationData.strings.Map_Locating, nil, coordinate))
case .selecting:
entries.append(.location(presentationData.theme, presentationData.strings.Map_SendThisLocation, presentationData.strings.Map_Locating, nil, nil))
let title: String
switch strongSelf.mode {
case .share:
title = presentationData.strings.Map_SendThisLocation
case .pick:
title = presentationData.strings.Map_SetThisLocation
}
entries.append(.location(presentationData.theme, title, presentationData.strings.Map_Locating, nil, nil))
case let .venue(venue):
entries.append(.location(presentationData.theme, presentationData.strings.Map_SendThisPlace, venue.venue?.title ?? "", venue, venue.coordinate))
let title: String
switch strongSelf.mode {
case .share:
title = presentationData.strings.Map_SendThisPlace
case .pick:
title = presentationData.strings.Map_SetThisPlace
}
entries.append(.location(presentationData.theme, title, venue.venue?.title ?? "", venue, venue.coordinate))
case .none:
let title: String
switch strongSelf.mode {
@ -380,7 +410,7 @@ final class LocationPickerControllerNode: ViewControllerTracingNode {
switch state.selectedLocation {
case .none:
if let userLocation = userLocation {
strongSelf.headerNode.mapNode.setMapCenter(coordinate: userLocation.coordinate, animated: previousUserLocation != nil)
strongSelf.headerNode.mapNode.setMapCenter(coordinate: userLocation.coordinate, isUserLocation: true, animated: previousUserLocation != nil)
}
strongSelf.headerNode.mapNode.resetAnnotationSelection()
case .selecting:
@ -421,9 +451,13 @@ final class LocationPickerControllerNode: ViewControllerTracingNode {
strongSelf.geocodingDisposable.set((reverseGeocodeLocation(latitude: coordinate.latitude, longitude: coordinate.longitude)
|> deliverOnMainQueue).start(next: { [weak self] placemark in
if let strongSelf = self {
var address = placemark?.fullAddress ?? ""
if address.isEmpty {
address = presentationData.strings.Map_Unknown
}
strongSelf.updateState { state in
var state = state
state.selectedLocation = .location(coordinate, placemark?.fullAddress)
state.selectedLocation = .location(coordinate, address)
return state
}
}
@ -434,8 +468,13 @@ final class LocationPickerControllerNode: ViewControllerTracingNode {
}
})
if case let .share(_, selfPeer, _) = self.mode, let peer = selfPeer {
self.headerNode.mapNode.userLocationAnnotation = LocationPinAnnotation(account: context.account, theme: self.presentationData.theme, peer: peer)
self.headerNode.mapNode.hasPickerAnnotation = true
}
self.listNode.updateFloatingHeaderOffset = { [weak self] offset, listTransition in
guard let strongSelf = self, let (layout, navigationBarHeight) = strongSelf.validLayout else {
guard let strongSelf = self, let (layout, navigationBarHeight) = strongSelf.validLayout, strongSelf.listNode.scrollEnabled else {
return
}
@ -494,7 +533,7 @@ final class LocationPickerControllerNode: ViewControllerTracingNode {
strongSelf.updateState { state in
var state = state
state.displayingMapModeOptions = false
state.selectedLocation = annotation.flatMap { .venue($0.location) } ?? .none
state.selectedLocation = annotation?.location.flatMap { .venue($0) } ?? .none
return state
}
}
@ -513,6 +552,8 @@ final class LocationPickerControllerNode: ViewControllerTracingNode {
self.listNode.backgroundColor = self.presentationData.theme.list.plainBackgroundColor
self.headerNode.updatePresentationData(self.presentationData)
self.optionsNode.updatePresentationData(self.presentationData)
self.shadeNode.backgroundColor = self.presentationData.theme.list.plainBackgroundColor
self.innerShadeNode.backgroundColor = self.presentationData.theme.list.plainBackgroundColor
self.searchContainerNode?.updatePresentationData(self.presentationData)
}
@ -604,10 +645,24 @@ final class LocationPickerControllerNode: ViewControllerTracingNode {
let optionsHeight: CGFloat = 38.0
let pickingCustomLocation = self.state.selectedLocation.isCustom
var actionHeight: CGFloat?
self.listNode.forEachItemNode { itemNode in
if let itemNode = itemNode as? LocationActionListItemNode {
if actionHeight == nil {
actionHeight = itemNode.frame.height
}
}
}
let topInset: CGFloat = floor((layout.size.height - navigationHeight) / 2.0 + navigationHeight)
let overlap: CGFloat = 6.0
let headerHeight: CGFloat
if let listOffset = self.listOffset {
if pickingCustomLocation, let actionHeight = actionHeight {
self.listOffset = topInset
headerHeight = layout.size.height - actionHeight - layout.intrinsicInsets.bottom + overlap - 2.0
} else if let listOffset = self.listOffset {
headerHeight = max(0.0, listOffset + overlap)
} else {
headerHeight = topInset + overlap
@ -615,14 +670,27 @@ final class LocationPickerControllerNode: ViewControllerTracingNode {
let headerFrame = CGRect(origin: CGPoint(), size: CGSize(width: layout.size.width, height: headerHeight))
transition.updateFrame(node: self.headerNode, frame: headerFrame)
self.headerNode.updateLayout(layout: layout, navigationBarHeight: navigationHeight, padding: self.state.displayingMapModeOptions ? optionsHeight : 0.0, size: headerFrame.size, transition: transition)
transition.updateFrame(node: self.listNode, frame: CGRect(origin: CGPoint(), size: layout.size))
var insets = layout.insets(options: [.input])
let (duration, curve) = listViewAnimationDurationAndCurve(transition: transition)
self.listNode.transaction(deleteIndices: [], insertIndicesAndItems: [], updateIndicesAndItems: [], options: [.Synchronous, .LowLatency], scrollToItem: nil, updateSizeAndInsets: ListViewUpdateSizeAndInsets(size: layout.size, insets: UIEdgeInsets(top: topInset, left: 0.0, bottom: layout.intrinsicInsets.bottom, right: 0.0), headerInsets: UIEdgeInsets(top: navigationHeight, left: 0.0, bottom: layout.intrinsicInsets.bottom, right: 0.0), scrollIndicatorInsets: UIEdgeInsets(top: topInset + 3.0, left: 0.0, bottom: layout.intrinsicInsets.bottom, right: 0.0), duration: duration, curve: curve), stationaryItemRange: nil, updateOpaqueState: nil, completion: { _ in })
self.listNode.scrollEnabled = !self.state.selectedLocation.isCustom
let scrollToItem: ListViewScrollToItem?
if pickingCustomLocation {
scrollToItem = ListViewScrollToItem(index: 0, position: .top(0.0), animated: true, curve: curve, directionHint: .Up)
} else {
scrollToItem = nil
}
self.listNode.transaction(deleteIndices: [], insertIndicesAndItems: [], updateIndicesAndItems: [], options: [.Synchronous, .LowLatency], scrollToItem: scrollToItem, updateSizeAndInsets: ListViewUpdateSizeAndInsets(size: layout.size, insets: UIEdgeInsets(top: topInset, left: 0.0, bottom: layout.intrinsicInsets.bottom, right: 0.0), headerInsets: UIEdgeInsets(top: navigationHeight, left: 0.0, bottom: layout.intrinsicInsets.bottom, right: 0.0), scrollIndicatorInsets: UIEdgeInsets(top: topInset + 3.0, left: 0.0, bottom: layout.intrinsicInsets.bottom, right: 0.0), duration: duration, curve: curve), stationaryItemRange: nil, updateOpaqueState: nil, completion: { _ in })
self.listNode.scrollEnabled = !pickingCustomLocation
var listFrame: CGRect = CGRect(origin: CGPoint(), size: layout.size)
if pickingCustomLocation {
listFrame.origin.y = headerHeight - topInset - overlap
}
transition.updateFrame(node: self.listNode, frame: listFrame)
transition.updateAlpha(node: self.shadeNode, alpha: pickingCustomLocation ? 1.0 : 0.0)
transition.updateFrame(node: self.shadeNode, frame: CGRect(x: 0.0, y: listFrame.minY + topInset + (actionHeight ?? 0.0) - 3.0, width: layout.size.width, height: 10000.0))
self.shadeNode.isUserInteractionEnabled = pickingCustomLocation
self.innerShadeNode.frame = CGRect(x: 0.0, y: 4.0, width: layout.size.width, height: 10000.0)
self.innerShadeNode.alpha = layout.intrinsicInsets.bottom > 0.0 ? 1.0 : 0.0
self.layoutActivityIndicator(transition: transition)
@ -645,5 +713,6 @@ final class LocationPickerControllerNode: ViewControllerTracingNode {
func updateSendActionHighlight(_ highlighted: Bool) {
self.headerNode.updateHighlight(highlighted)
self.shadeNode.backgroundColor = highlighted ? self.presentationData.theme.list.itemHighlightedBackgroundColor : self.presentationData.theme.list.plainBackgroundColor
}
}

View File

@ -5821,7 +5821,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
return
}
let hasLiveLocation = peer.id.namespace != Namespaces.Peer.SecretChat && peer.id != strongSelf.context.account.peerId && !strongSelf.presentationInterfaceState.isScheduledMessages
let controller = LocationPickerController(context: strongSelf.context, mode: .share(peer: peer, selfPeer: peer, hasLiveLocation: hasLiveLocation), completion: { [weak self] location, _ in
let controller = LocationPickerController(context: strongSelf.context, mode: .share(peer: peer, selfPeer: selfPeer, hasLiveLocation: hasLiveLocation), completion: { [weak self] location, _ in
guard let strongSelf = self else {
return
}