Anonymous
Интерактивная панель поиска с вытягиванием вниз
Сообщение
Anonymous » 04 май 2024, 18:18
Интерактивная раскрывающаяся панель поиска
Я пытаюсь реализовать интерактивную раскрывающуюся панель поиска с помощью UIViewPropertyAnimator. Но я новичок в разработке iOS. Поэтому я часто делаю ошибки. Пожалуйста, просмотрите этот код и подскажите мне какое-нибудь решение.
Код: Выделить всё
import UIKit
class ViewController: UIViewController {
private let searchController = UISearchController(searchResultsController: nil)
let scrollView = UIScrollView()
var transitionInProgress: Bool = false
var searchAnimator: UIViewPropertyAnimator?
var isSearchBarShowing: Bool = false
var cachedSearchBarFrame: CGRect = .init()
override func viewDidLoad() {
super.viewDidLoad()
self.title = "Home"
cachedSearchBarFrame = searchController.searchBar.frame
self.navigationController?.navigationBar.backgroundColor = .white
view.backgroundColor = .white
view.addSubview(scrollView)
scrollView.translatesAutoresizingMaskIntoConstraints = false
scrollView.delegate = self
searchController.searchResultsUpdater = self
searchController.obscuresBackgroundDuringPresentation = false
searchController.searchBar.placeholder = "Search"
searchController.delegate = self
navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .search, target: self, action: #selector(searchButtonTapped))
NSLayoutConstraint.activate([
scrollView.topAnchor.constraint(equalTo: view.topAnchor),
scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
])
navigationItem.titleView = searchController.searchBar
navigationItem.titleView?.alpha = 0
searchAnimator = UIViewPropertyAnimator(duration: 2, curve: .easeIn) {
self.searchController.searchBar.frame = self.cachedSearchBarFrame
self.navigationItem.titleView?.alpha = 1
}
searchAnimator?.addCompletion { position in
if position == .end {
self.isSearchBarShowing = true
} else if position == .start {
self.searchAnimator?.isReversed = false
}
}
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
scrollView.contentSize = .init(width: self.view.frame.width, height: 2000)
}
@objc func searchButtonTapped() {
if isSearchBarShowing {
hideSearchBar()
} else {
showSearchBar()
}
}
func showSearchBar() {
isSearchBarShowing = true
searchController.searchBar.frame = CGRect(x: 0, y: -self.cachedSearchBarFrame.height, width: self.cachedSearchBarFrame.width, height: self.cachedSearchBarFrame.height)
self.navigationItem.titleView?.alpha = 0
// Apply animation
UIView.animate(withDuration: 1) {
self.searchController.searchBar.frame = self.cachedSearchBarFrame
self.navigationItem.titleView?.alpha = 1
}
}
func hideSearchBar() {
isSearchBarShowing = false
UIView.animate(withDuration: 1) {
self.searchController.searchBar.frame = CGRect(x: 0, y: -self.cachedSearchBarFrame.height, width: self.cachedSearchBarFrame.width, height: self.cachedSearchBarFrame.height)
self.navigationItem.titleView?.alpha = 0
}
}
}
extension ViewController: UISearchResultsUpdating {
func updateSearchResults(for searchController: UISearchController) {
// Implement your search logic here
}
}
extension ViewController: UIScrollViewDelegate {
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let pullThreshold: CGFloat = -100
if scrollView.contentOffset.y + scrollView.contentInset.top < pullThreshold {
if !transitionInProgress && scrollView.isDragging && scrollView.isTracking {
let fractionComplete = -(scrollView.contentOffset.y + 200) / 100
searchAnimator?.fractionComplete = min(max(fractionComplete, 0), 1)
print(min(max(fractionComplete, 0), 1))
searchAnimator?.startAnimation()
}
}
}
func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
let fractionComplete = -(scrollView.contentOffset.y + 200) / 100
if fractionComplete < 1 && fractionComplete > 0 {
searchAnimator?.isReversed = true
searchAnimator?.startAnimation()
}
}
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
searchAnimator?.stopAnimation(true)
if !isSearchBarShowing {
searchController.searchBar.frame = CGRect(x: 0, y: -self.cachedSearchBarFrame.height, width: self.cachedSearchBarFrame.width, height: self.cachedSearchBarFrame.height)
self.navigationItem.titleView?.alpha = 0
searchAnimator?.fractionComplete = 0
}
}
}
extension ViewController: UISearchControllerDelegate {
}
В этом коде я попытался реализовать раскрывающуюся панель поиска, но она хорошо работает при первом нажатии, но не при последующих. Пожалуйста, исправьте ошибку в этом коде.
Подробнее здесь:
https://stackoverflow.com/questions/784 ... -searchbar
1714835919
Anonymous
[b]Интерактивная раскрывающаяся панель поиска[/b] Я пытаюсь реализовать интерактивную раскрывающуюся панель поиска с помощью UIViewPropertyAnimator. Но я новичок в разработке iOS. Поэтому я часто делаю ошибки. Пожалуйста, просмотрите этот код и подскажите мне какое-нибудь решение. [code]import UIKit class ViewController: UIViewController { private let searchController = UISearchController(searchResultsController: nil) let scrollView = UIScrollView() var transitionInProgress: Bool = false var searchAnimator: UIViewPropertyAnimator? var isSearchBarShowing: Bool = false var cachedSearchBarFrame: CGRect = .init() override func viewDidLoad() { super.viewDidLoad() self.title = "Home" cachedSearchBarFrame = searchController.searchBar.frame self.navigationController?.navigationBar.backgroundColor = .white view.backgroundColor = .white view.addSubview(scrollView) scrollView.translatesAutoresizingMaskIntoConstraints = false scrollView.delegate = self searchController.searchResultsUpdater = self searchController.obscuresBackgroundDuringPresentation = false searchController.searchBar.placeholder = "Search" searchController.delegate = self navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .search, target: self, action: #selector(searchButtonTapped)) NSLayoutConstraint.activate([ scrollView.topAnchor.constraint(equalTo: view.topAnchor), scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor), scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor), scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor) ]) navigationItem.titleView = searchController.searchBar navigationItem.titleView?.alpha = 0 searchAnimator = UIViewPropertyAnimator(duration: 2, curve: .easeIn) { self.searchController.searchBar.frame = self.cachedSearchBarFrame self.navigationItem.titleView?.alpha = 1 } searchAnimator?.addCompletion { position in if position == .end { self.isSearchBarShowing = true } else if position == .start { self.searchAnimator?.isReversed = false } } } override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() scrollView.contentSize = .init(width: self.view.frame.width, height: 2000) } @objc func searchButtonTapped() { if isSearchBarShowing { hideSearchBar() } else { showSearchBar() } } func showSearchBar() { isSearchBarShowing = true searchController.searchBar.frame = CGRect(x: 0, y: -self.cachedSearchBarFrame.height, width: self.cachedSearchBarFrame.width, height: self.cachedSearchBarFrame.height) self.navigationItem.titleView?.alpha = 0 // Apply animation UIView.animate(withDuration: 1) { self.searchController.searchBar.frame = self.cachedSearchBarFrame self.navigationItem.titleView?.alpha = 1 } } func hideSearchBar() { isSearchBarShowing = false UIView.animate(withDuration: 1) { self.searchController.searchBar.frame = CGRect(x: 0, y: -self.cachedSearchBarFrame.height, width: self.cachedSearchBarFrame.width, height: self.cachedSearchBarFrame.height) self.navigationItem.titleView?.alpha = 0 } } } extension ViewController: UISearchResultsUpdating { func updateSearchResults(for searchController: UISearchController) { // Implement your search logic here } } extension ViewController: UIScrollViewDelegate { func scrollViewDidScroll(_ scrollView: UIScrollView) { let pullThreshold: CGFloat = -100 if scrollView.contentOffset.y + scrollView.contentInset.top < pullThreshold { if !transitionInProgress && scrollView.isDragging && scrollView.isTracking { let fractionComplete = -(scrollView.contentOffset.y + 200) / 100 searchAnimator?.fractionComplete = min(max(fractionComplete, 0), 1) print(min(max(fractionComplete, 0), 1)) searchAnimator?.startAnimation() } } } func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) { let fractionComplete = -(scrollView.contentOffset.y + 200) / 100 if fractionComplete < 1 && fractionComplete > 0 { searchAnimator?.isReversed = true searchAnimator?.startAnimation() } } func scrollViewWillBeginDragging(_ scrollView: UIScrollView) { searchAnimator?.stopAnimation(true) if !isSearchBarShowing { searchController.searchBar.frame = CGRect(x: 0, y: -self.cachedSearchBarFrame.height, width: self.cachedSearchBarFrame.width, height: self.cachedSearchBarFrame.height) self.navigationItem.titleView?.alpha = 0 searchAnimator?.fractionComplete = 0 } } } extension ViewController: UISearchControllerDelegate { } [/code] В этом коде я попытался реализовать раскрывающуюся панель поиска, но она хорошо работает при первом нажатии, но не при последующих. Пожалуйста, исправьте ошибку в этом коде. Подробнее здесь: [url]https://stackoverflow.com/questions/78428249/interactive-pulling-down-searchbar[/url]