Schwimmender Ball mit hoher Nachahmung des WeChat-Artikels
In der neuesten Version 6.6.7 von WeChat wurde eine neue Artikel-Floating-Ball-Funktion hinzugefügt. Während Sie den Artikel lesen, sendet Ihnen plötzlich ein Freund eine dringende Nachricht und Sie müssen sofort antworten. Oder vielleicht kommen Sie gerade an einer Snackbar vorbei und müssen die WeChat-Zahlung vorübergehend öffnen oder das Lesen vorübergehend unterbrechen. Früher konnte ich nur die Artikeldetailseite verlassen und nach Abschluss meiner Arbeit konnte ich den Originalartikel nebeneinander finden. Für starke WeChat-Nutzer wie uns ist es jedes Mal sehr schmerzhaft, wenn wir in diese Situation geraten. Daher wurde diese Funktion beim Start sofort auf die neueste Version aktualisiert. Diese Funktion fühlt sich an, als würde man einen engen Freund treffen, und sie ist sehr einfach zu verwenden. Sie können es durch die Animation unten spüren
Tatsächlich gibt es das Konzept der schwebenden Bälle schon seit langem. Zum Beispiel der Verkehrsüberwachungsball von 360 Assistant, der iPhone-eigene AssistiveTouch (dieser niedliche kleine weiße Ball) usw.
Wenn Ihnen die Github-Adresse gefällt, klicken Sie darauf ❤️
Nachdem ich es erlebt habe, jucken meine Hände und ich kann nicht anders, als es nachzuahmen. Wenn Ihre APP diese Funktion integrieren kann, kann sie meiner Meinung nach Ihre APP sofort auf ein neues Niveau heben. Okay, lassen Sie uns nacheinander die technischen Kernpunkte des schwebenden Balls im WeChat-Artikel analysieren:
Wenn wir die Bildschirmrandgeste verwenden, um die Ansicht zu öffnen, wird in der unteren rechten Ecke eine Eingabeaufforderung mit abgerundeten Ecken angezeigt, die sich mit dem Fortschritt der Geste bewegt. Wie erhalte ich den Fortschritt von UIScreenEdgePanGestureRecognizer
? Da interactivePopGestureRecognizer
gekapselt ist, können wir seine Aktion nicht einbinden, um den Gestenfortschritt darin abzurufen. Deshalb müssen wir einen anderen Weg finden.
self . interactivePopGestureRecognizer ? . delegate = self
func gestureRecognizer ( _ gestureRecognizer : UIGestureRecognizer , shouldRecognizeSimultaneouslyWith otherGestureRecognizer : UIGestureRecognizer ) -> Bool {
return true
}
UIScreenEdgePanGestureRecognizer
zum UINavigationController hinzu, um den Fortschritt der Pop-Geste zu erhalten. let gesture = UIScreenEdgePanGestureRecognizer ( target : self , action : #selector ( handleNavigationTransition ( gesture : ) ) )
gesture . edges = . left
self . view . addGestureRecognizer ( gesture )
Auf diese Weise gibt es zwei UIScreenEdgePanGestureRecognizer
, die gleichzeitig reagieren können. Der mit dem System gelieferte behält weiterhin die ursprüngliche Logik bei, und der neue, den wir hinzugefügt haben, wird verwendet, um den Fortschritt der Pop-Geste zu ermitteln Harmonie und Spaß haben. Diese Technik von mir wird auch in diesem Artikel unter iOS verwendet: Integrieren Sie Mainstream-APP-Profilseiten (wie Jianshu, Weibo usw.) in einer Minute
Da der schwebende Ball auf jeder Seite aufgehängt werden kann, muss er auf einem neuen UIWindow platziert werden. Wenn beispielsweise die Systemtastatur angezeigt wird, wird sie von einem UIRemoteKeyboardWindow
gehostet. Dann hängt der Lebenszyklus dieses Fensters nicht von einer bestimmten Seite ab. Daher ist es besser, einen Singleton für die Implementierung zu verwenden. Dieser Code ist relativ verstreut. Sie können ihn verstehen, indem Sie sich direkt den Quellcode ansehen.
override func point ( inside point : CGPoint , with event : UIEvent ? ) -> Bool {
let roundEntryViewPoint = self . convert ( point , to : roundEntryView )
if roundEntryView . point ( inside : roundEntryViewPoint , with : event ) == true {
return true
}
let collectViewPoint = self . convert ( point , to : collectView )
if collectView . point ( inside : collectViewPoint , with : event ) == true {
return true
}
return false
}
UIBezierPath
und ermitteln Sie ihn dann mit der Methode contains(point)
von CGPath
. func updateBGLayerPath ( isSmall : Bool ) {
var ratio : CGFloat = 1
if !isSmall {
ratio = 1.3
}
let path = UIBezierPath ( )
path . move ( to : CGPoint ( x : viewSize . width , y : ( 1 - ratio ) * viewSize . height ) )
path . addLine ( to : CGPoint ( x : viewSize . width , y : viewSize . height ) )
path . addLine ( to : CGPoint ( x : ( 1 - ratio ) * viewSize . width , y : viewSize . height ) )
path . addArc ( withCenter : CGPoint ( x : viewSize . width , y : viewSize . height ) , radius : viewSize . width*ratio , startAngle : CGFloat ( Double . pi ) , endAngle : CGFloat ( Double . pi*3 / 2 ) , clockwise : true )
path . close ( )
bgLayer . path = path . cgPath
}
override func point ( inside point : CGPoint , with event : UIEvent ? ) -> Bool {
return bgLayer . path! . contains ( point )
}
Studierende, die nicht viel über dieses Thema wissen, können auf diesen Artikel verweisen. Ein Artikel zum Verständnis der Verwendung von Event Delivery, Responder Chain, hitTest und pointInside
Sie können sehen, dass der durch Klicken auf den schwebenden Ball geöffnete Artikel durch eine benutzerdefinierte Übergangsanimation implementiert wird, beginnend mit der Position des schwebenden Balls. Es gibt viele Artikel, die erklären, wie man Übergangsanimationen anpasst, aber ich empfehle Ihnen, diesen Artikel zu lesen, um schnell benutzerdefinierte Übergangseffekte und einen vollständigen Gestentreiber mit ein paar Codezeilen zu integrieren
Der schwebende Ball von WeChat verwendet relativ viele technische Punkte und der Code ist relativ verstreut. Wenn Ihre APP diese Funktion integrieren möchte, müssen Sie den Code sorgfältig verpacken. Ich denke, wie man eine Anforderung entwirft, ist wichtiger als wie man sie umsetzt. Beim Nachahmen habe ich festgestellt, dass es viele detaillierte Logiken gibt, die ineinandergreifen, und schließlich wird die von Ihnen verwendete Floating-Ball-Funktion vorgestellt. Es wird gesagt, dass Programmierer und Produktmanager ineinander verliebt sind. Hier möchte ich dem Produktmanager dieser Funktion einen Daumen hoch geben.
Wenn es Probleme mit dem Code gibt oder Sie Fragen haben, können Sie mir Feedback geben und ich werde mich so schnell wie möglich darum kümmern. Wenn Ihnen die Github-Adresse gefällt, klicken Sie darauf ❤️