Lazy var not initialized in containerView Swift 3 - Xcode 8 - ios

so I have this lazy var for a UIView in my messaging app. The View holds a textfield, and 2 buttons. We'll call it inputView. inputView has been created programmatically and whenever I present it via: present(chatLogController, animated: true) It works as expected. here is an image to show you:
However, whenever I place ChatLogVC inside of a container view and present it through an embedded segue with Interface Builder the view never gets displayed. Here is a picture
NOTE: The reason I am using the containerView is to have the header bar at the top.
Why would an embedded segue prevent the variable to be executed?
Here's my code
Presenting VC:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
**MARK: Performs the function below
self.showChatControllerForUser(user)
**MARK: Performs segue to VC which then performs the embed segue
self.performSegue(withIdentifier: "toChatLog", sender: nil)
}
**MARK: This function shows successfully the inputView
func showChatControllerForUser(_ user: messageUser) {
let chatLogController = ChatLogController(collectionViewLayout: UICollectionViewFlowLayout())
chatLogController.user = user
present(chatLogController, animated: true)
//navigationController?.pushViewController(chatLogController, animated: true)
}
ChatLogVC :
override func viewDidLoad() {
super.viewDidLoad()
collectionView?.collectionViewLayout = UICollectionViewFlowLayout()
user = segueUser
observeMessages()
print("CHAT LOG IS RUNNING")
collectionView?.showsVerticalScrollIndicator = false
collectionView?.contentInset = UIEdgeInsets(top: 8, left: 0, bottom: 8, right: 0)
// collectionView?.scrollIndicatorInsets = UIEdgeInsets(top: 0, left: 0, bottom: 50, right: 0)
collectionView?.alwaysBounceVertical = true
collectionView?.backgroundColor = UIColor.white
collectionView?.register(ChatMessageCell.self, forCellWithReuseIdentifier: cellId)
collectionView?.keyboardDismissMode = .interactive
//(inputContainerView)
collectionView?.bringSubview(toFront: inputContainerView)
}
lazy var inputContainerView: ChatInputContainerView = {
let chatInputContainerView = ChatInputContainerView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: 64))
chatInputContainerView.chatLogController = self
return chatInputContainerView
}()
InputView:
I have left out all of the UI Code
class ChatInputContainerView: UIView, UITextFieldDelegate {
weak var chatLogController: ChatLogController? {
didSet {
sendButton.addTarget(chatLogController, action: #selector(ChatLogController.handleSend), for: .touchUpInside)
uploadImageView.addGestureRecognizer(UITapGestureRecognizer(target: chatLogController, action: #selector(ChatLogController.handleUploadTap)))
}
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
chatLogController?.handleSend()
return true
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
My question is: Why doesn't the inputView get executed when the ChatLog is presented through a segue??

Related

Perform Segue is not working when i am using programmatic UI

I am creating an app for my personal project using programmaticUI and storyboard for the UI part, but i found an issue when i tried to performSegue from my "SecondViewController" to my "ThirdViewController" , i added the "identifier" in my segue like usual:
And then i called the "performSegue" from my SecondViewController:
import UIKit
class SecondViewController: UIViewController {
private var myItem = [SecondItem]()
lazy var myTableView : UITableView = {
let myTable = UITableView()
myTable.translatesAutoresizingMaskIntoConstraints = false
return myTable
}()
private let myContentView : UIView = {
let view = UIView()
view.backgroundColor = .gray
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
lazy var label : UILabel = {
let myLabel = UILabel()
myLabel.text = "Hello"
return myLabel
}()
private let unameTextField : UITextField = {
let txtField = UITextField()
txtField.backgroundColor = .white
txtField.placeholder = "Username"
txtField.borderStyle = .roundedRect
txtField.translatesAutoresizingMaskIntoConstraints = false
return txtField
}()
private let pwordTxtField : UITextField = {
let txtField = UITextField()
txtField.placeholder = "Password"
txtField.borderStyle = .roundedRect
txtField.translatesAutoresizingMaskIntoConstraints = false
return txtField
}()
private let loginBtn : UIButton = {
let btn = UIButton(type: .system)
btn.backgroundColor = .blue
btn.setTitle("Login", for: .normal)
btn.tintColor = .white
btn.layer.cornerRadius = 5
btn.clipsToBounds = true
btn.translatesAutoresizingMaskIntoConstraints = false
btn.addTarget(self, action: #selector(btnPressed), for: .touchUpInside)
return btn
}()
//I called the "performSegue" here
#objc func btnPressed() {
performSegue(withIdentifier: "gotoBla", sender: self)
print("button pressed")
}
lazy var imageView : UIImageView = {
let image = UIImage(named: "image_4")
let imageView = UIImageView(image: image)
imageView.translatesAutoresizingMaskIntoConstraints = false
return imageView
}()
func setAutoLayout(){
let guide = view.safeAreaLayoutGuide
myContentView.anchor(top: guide.topAnchor, left: view.leftAnchor, bottom: nil, right: view.rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: view.frame.height / 3, enableInsets: true)
imageView.anchor(top: myContentView.topAnchor, left: nil , bottom: nil , right: nil , paddingTop: 10, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 80, height: 80, enableInsets: true)
imageView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
unameTextField.anchor(top: imageView.bottomAnchor, left: myContentView.leftAnchor, bottom: nil, right: myContentView.rightAnchor, paddingTop: 10, paddingLeft: 20, paddingBottom: 5, paddingRight: 20, width: 0, height: 40, enableInsets: true)
pwordTxtField.anchor(top: unameTextField.bottomAnchor, left: myContentView.leftAnchor, bottom: nil, right: myContentView.rightAnchor, paddingTop: 30, paddingLeft: 20, paddingBottom: 0, paddingRight: 20, width: 0, height: 40, enableInsets: true)
loginBtn.anchor(top: pwordTxtField.bottomAnchor, left: myContentView.leftAnchor, bottom: nil, right: myContentView.rightAnchor , paddingTop: 20, paddingLeft: 20, paddingBottom: 0, paddingRight: 20, width: 0, height: 40, enableInsets: true)
//TableView
myTableView.topAnchor.constraint(equalTo: myContentView.bottomAnchor).isActive = true
myTableView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
myTableView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
myTableView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
}
override func viewDidLoad() {
super.viewDidLoad()
myItem.append(SecondItem(text: "first"))
myItem.append(SecondItem(text: "Second"))
myItem.append(SecondItem(text: "Third"))
view.backgroundColor = .white
view.addSubview(myContentView)
myContentView.addSubview(unameTextField)
myContentView.addSubview(pwordTxtField)
myContentView.addSubview(loginBtn)
myContentView.addSubview(imageView)
myTableView.register(SecondTableViewCell.self, forCellReuseIdentifier: K.SecondTableViewCell.identifier)
myTableView.delegate = self
myTableView.dataSource = self
view.addSubview(myTableView)
setAutoLayout()
}
}
extension SecondViewController : UITableViewDelegate {
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print(indexPath.row)
}
}
extension SecondViewController : UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
myItem.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: K.SecondTableViewCell.identifier, for: indexPath) as! SecondTableViewCell
cell.second = myItem[indexPath.row]
cell.selectionStyle = .none
return cell
}
}
And for the Third View Controller, i am not yet adding some code in there
import UIKit
class ThirdViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
}
But everytime i run the app and click the login button,it always gave me this error:
This is what my app looks like:
Do i miss something here? I am a beginner by the way, i hope you guys can help me. Thank you
When posting questions here, it would be good for you to take a few minutes to review How to Ask
However, based on the little bit of info you've provided...
Almost certainly the problem is that you are adding View Controllers in Storyboard and then improperly trying to use them via code.
For example, I'm guessing that you have code in your "first" view controller to load and display SecondViewController like this:
#objc func showSecondTapped(_ sender: Any) {
let vc = SecondViewController()
navigationController?.pushViewController(vc, animated: true)
}
and then in SecondViewController you're trying to use the Storyboard associated segue with this:
#objc func btnPressed(_ sender: Any) {
performSegue(withIdentifier: "gotoBla", sender: self)
print("button pressed")
}
However, that segue doesn't exist as part of SecondViewController code ... it is part of the Storyboard object.
Back in your first view controller, if you load and push to SecondViewController like this:
#objc func showSecondTapped(_ sender: Any) {
if let vc = storyboard?.instantiateViewController(withIdentifier: "secondVC") as? SecondViewController {
navigationController?.pushViewController(vc, animated: true)
}
}
you will then be able to call performSegue because you loaded it from the Storyboard.
if let vc = storyboard?.instantiateViewController(withIdentifier: "secondVC") as? SecondViewController {
navigationController?.pushViewController(vc, animated: true)
// if navigationController?.pushViewController doesn't work you can try this
present(vc, animated: true) {
// anything you want to perform after presenting new screen
}
// and try this to show in full screen with different transition effect
vc.modalTransitionStyle = .crossDissolve
vc.modalPresentationStyle = .fullScreen
present(vc, animated: true) {
// anything you want to perform after presenting new screen
}
}

UIPageViewController within a UIScrollView appears fullscreen even though CGRect is set - returns to correct frame values as soon as user scrolls

I have a UIPageViewController named SwipingPhotosController where the user swipes horizontally to view images. I have implemented this SwipingPhotosController within a UIScrollView by giving it CGRect values. Then I write a function that basically does the stretchy header effect of zooming in & out when the user scrolls up or down.
Everything works except that when I tried to add another view beneath the SwipingPhotosController, as soon as the controller is loaded, the image appears full screen. As soon as I scroll slightly, it all returns to the accurate position.
This is what I get when I press run in simulator - a full screen blown out pageviewcontroller:
Here the view goes back to normal as soon as I scroll slightly
Note: This bug occurs only when I add the nameLabel beneath the imageView (swipingPhotosController.view)
class ProfileController: UIViewController, UIScrollViewDelegate {
var user: User! {
didSet{
swipingPhotosController.user = user
}
}
lazy var scrollProfileView: UIScrollView = {
let sv = UIScrollView()
sv.delegate = self
sv.backgroundColor = TDGSettings
sv.alwaysBounceVertical = true
sv.contentInsetAdjustmentBehavior = .never
return sv
}()
let nameLabel: UILabel = {
let label = UILabel()
label.font = .systemFont(ofSize: 12, weight: .bold)
label.textColor = .white
label.numberOfLines = 2
label.textAlignment = .left
return label
}()
let swipingPhotosController = SwipingPhotosController(transitionStyle: .scroll, navigationOrientation: .horizontal)
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = TDGSettings
setupViews()
}
fileprivate func setupViews() {
view.addSubview(scrollProfileView)
scrollProfileView.fillSuperview()
let imageView = swipingPhotosController.view!
scrollProfileView.addSubview(imageView)
let blurEffect = UIBlurEffect(style: .systemThinMaterialDark)
let visualEffectView = UIVisualEffectView(effect: blurEffect)
view.addSubview(visualEffectView)
visualEffectView.anchor(top: view.topAnchor, leading: view.leadingAnchor, bottom: view.safeAreaLayoutGuide.topAnchor, trailing: view.trailingAnchor)
scrollProfileView.addSubview(nameLabel)
nameLabel.anchor(top: imageView.bottomAnchor, leading: view.leadingAnchor, bottom: nil, trailing: view.trailingAnchor, padding: .init(top: 16, left: 16, bottom: 0, right: 16))
nameLabel.text = "First Name"
}
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
let imageView = swipingPhotosController.view!
imageView.frame = CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.width)
}
//STRETCHY HEADER EFFECT
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let changeY = -scrollView.contentOffset.y
var width = view.frame.width + changeY * 2
width = max(view.frame.width, width)
let imageView = swipingPhotosController.view!
imageView.frame = CGRect(x: min(0, -changeY), y: min(0, -changeY), width: width, height: width)
}
}
As requested added code for SwipingPhotosController
import Foundation
import LBTATools
class SwipingPhotosController: UIPageViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate {
var user: User! {
didSet{
controllers = user.swipingUrls.map({ (url) -> UIViewController in
let photoController = PhotosController(imageUrl: url)
return photoController
})
setViewControllers([controllers.first!], direction: .forward, animated: false, completion: nil)
}
}
var controllers = [UIViewController]()
override func viewDidLoad() {
super.viewDidLoad()
dataSource = self
delegate = self
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
let index = self.controllers.firstIndex(where: {$0 == viewController}) ?? 0
if index == 0 {return nil}
return controllers[index - 1]
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
let index = self.controllers.firstIndex(where: {$0 == viewController}) ?? 0
if index == controllers.count - 1 {return nil}
return controllers[index + 1]
}
}
class PhotosController: UIViewController {
let imageView = UIImageView()
init(imageUrl: String) {
if let url = URL(string: imageUrl){
imageView.sd_setImage(with: url)
}
super.init(nibName: nil, bundle: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
imageView.contentMode = .scaleAspectFill
view.addSubview(imageView)
imageView.contentMode = .scaleAspectFill
imageView.clipsToBounds = true
imageView.fillSuperview()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
The problem is that you are setting swipingPhotosController's frame in viewWillLayoutSubviews() --- but the views have not yet been laid out.
You need to do that in viewDidLayoutSubviews() (did not will).
However, viewDidLayoutSubviews() gets called many times, particularly since you are changing the frame again in scrollViewDidScroll().
So, you need to set a flag to only set the frame in viewDidLayoutSubviews() once (or again, if the scrollView frame has changed).
Not being sure how or when you were setting your SwipingPhotosController's properties, I did it this way to test:
// add a class property
var savedScrollViewWidth: CGFloat = 0.0
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
if scrollProfileView.frame.width != savedScrollViewWidth {
savedScrollViewWidth = scrollProfileView.frame.width
let imageView = swipingPhotosController.view!
imageView.frame = CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.width)
}
}
See if that gets your layout working correctly.

How to increase the width of custom cells in UITableView

I have created the UITableView with the custom UITableViewCell. But the problem which I am getting is the width of the cells is not the frame width though I have assigned in the CGReact. Please have a look over my code :
CustomTableViewCell Class:
import UIKit
class CustomTableViewCell: UITableViewCell {
lazy var backView : UIView = {
let view = UIView(frame: CGRect(x: 10, y: 6, width: self.frame.width, height: 76))
view.backgroundColor = .red
view.layer.applySketchShadow()
return view
}()
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
lazy var iconTime : UIImageView = {
var object = UIImageView(frame: CGRect(x: 10, y: 54, width: 12, height: 12))
object.image = #imageLiteral(resourceName: "clock")
return object
}()
lazy var notification : UILabel = {
var object = UILabel(frame: CGRect(x: 10, y: 7, width: backView.frame.width, height: 40))
object.adjustsFontSizeToFitWidth = true
object.minimumScaleFactor = 0.5
object.font = object.font.withSize(28.0)
object.numberOfLines = 3
return object
}()
lazy var notificationTime : UILabel = {
var object = UILabel(frame: CGRect(x: 30, y: 40, width: backView.frame.width, height: 40))
object.adjustsFontSizeToFitWidth = true
object.minimumScaleFactor = 0.5
object.font = object.font.withSize(12.0)
return object
}()
override func layoutSubviews() {
contentView.backgroundColor = UIColor.clear
backgroundColor = UIColor.clear
backView.layer.cornerRadius = 5
backView.clipsToBounds = true
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
addSubview(backView)
[notification, notificationTime, iconTime].forEach(backView.addSubview(_:))
}
}
And my view controller as follows :
import UIKit
class UserModal {
var tableView = UITableView()
var notification: String?
var notificationTime : String?
init(notification: String, notificationTime: String) {
self.notification = notification
self.notificationTime = notificationTime
}
}
class newNotificationController : UIViewController {
var tableView = UITableView()
var userMod = [UserModal]()
override func viewDidLoad() {
super.viewDidLoad()
setTableView()
userMod.append(UserModal(notification: "Data ", notificationTime: "Time"))
userMod.append(UserModal(notification: "This is some Notification which needs to be populated in the Grid view for testing but lets see what is happening here!! ", notificationTime: "12-12-1212 12:12:12"))
userMod.append(UserModal(notification: "Data ", notificationTime: "Time"))
}
func setTableView() {
tableView.frame = self.view.frame
tableView.backgroundColor = UIColor.clear
tableView.delegate = self
tableView.dataSource = self
tableView.separatorColor = UIColor.clear
self.view.addSubview(tableView)
tableView.register(CustomTableViewCell.self, forCellReuseIdentifier: "cell")
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
navigationController?.setNavigationBarHidden(true, animated: animated)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
navigationController?.setNavigationBarHidden(false, animated: animated)
}
}
extension newNotificationController: UITableViewDelegate , UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return userMod.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as? CustomTableViewCell else { fatalError("Unable to populate Notification History")}
cell.notification.text = userMod[indexPath.row].notification
cell.notificationTime.text = userMod[indexPath.row].notificationTime
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 85
}
}
Please have a look over the result:
I am not getting it why the width of my cells is the width of the frame. Any help will be highly appreciated. Thanks!!
The problem is in this code is frame width, somehow the width of the self is not the width of a device, so because of this, you are facing this issue.
lazy var backView : UIView = {
let view = UIView(frame: CGRect(x: 10, y: 6, width: self.frame.width, height: 76))
view.backgroundColor = .red
view.layer.applySketchShadow()
return view
}()
To resolve this issue you can set frame like this
let view = UIView(frame: CGRect(x: 10, y: 6, width: UIScreen.main.bounds.size.width - 10, height: 76))
You set the width your view
UIView(frame: CGRect(x: 5, y: 6, width: self.frame.width - 10,
height: 76))
tableView.frame = CGRect(x: 0, y: 0, width:
self.view.frame.size.width, height: self.view.frame.size.height)
you need to give constraint to the tableview. Top, Leading, Trailing, Bottom.
put this tableView.translatesAutoresizingMaskIntoConstraints = false line in your function
func setTableView() {
tableView.frame = self.view.frame
tableView.backgroundColor = UIColor.clear
tableView.delegate = self
tableView.dataSource = self
tableView.separatorColor = UIColor.clear
self.view.addSubview(tableView)
tableView.translatesAutoresizingMaskIntoConstraints = false //add this line
tableView.register(CustomTableViewCell.self, forCellReuseIdentifier: "cell")
}
and change width: UIScreen.main.bounds.size.width - 10 it.
thanks..

UIView of TableView can't scroll or tap

What I did was when the search controller is clicked, it shows a View with a tableView in it. (like Instagram) . It shows the tableView but it cannot interact with it.
I was doing some research since people had come across this before here. Here are the things I've tried:
Bring subView to the front
have set tableView.isUserInteractionEnabled = true -> Have also ran on iPhone
Have set tableViewHeight to ScreenHeight
But the tableView still doesn't want to scroll/click!
Here's the relevant code that I have if it helps,
Controller with search bar and collection views:
class UserSearchController: UICollectionViewController, UICollectionViewDelegateFlowLayout,UISearchBarDelegate, UISearchDisplayDelegate {
let cellId = "cellId"
let searchBar: UISearchBar = {
let sb = UISearchBar()
sb.placeholder = "Search"
return sb
}()
func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
searchBar.setShowsCancelButton(true, animated: true)
tableView.isHidden = false
}
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
searchBar.setShowsCancelButton(true, animated: true)
}
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
searchBar.resignFirstResponder()
searchBar.setShowsCancelButton(false, animated: true)
searchBar.text = ""
tableView.isHidden = true
}
let tableView: UIView = {
let tv = SearchUsersTv()
tv.isUserInteractionEnabled = true
tv.bringSubview(toFront: tv)
tv.clipsToBounds = false
return tv
}()
override func viewDidLoad() {
super.viewDidLoad()
collectionView?.register(UserProfileVideoCell.self, forCellWithReuseIdentifier: cellId)
view.addSubview(tableView)
tableView.isHidden = true
}
Here's the code for the relevant code for the tableView (SearchUsersTv):
class SearchUsersTv: UIView, UITableViewDelegate, UITableViewDataSource {
let cellId = "cellId"
var tableView = UITableView()
override init(frame: CGRect){
super.init(frame: frame)
setupTv()
}
func setupTv() {
let screenHeight = UIScreen.main.bounds.height
let screenWidth = UIScreen.main.bounds.width
tableView.delegate = self
tableView.dataSource = self
tableView.register(UITableViewCell.self, forCellReuseIdentifier: cellId)
tableView.isUserInteractionEnabled = true
tableView = UITableView(frame: CGRect(x: 0, y: 0, width: screenWidth, height: screenHeight))
self.addSubview(tableView)
bringSubview(toFront: tableView)
}
Problem to fix: Make tableView scroll and click
Thank you in advanced!
Your problems is that you are initialising your custom class in wrongly way, you need call SearchUsersTv(frame: instead of SearchUsersTv() for initialisation because all your tableView setup happen on setupTv() which is called in SearchUsersTv(frame: initialisation only
replace your tableView inline creation by this
let tableView: UIView = {
let screenHeight = UIScreen.main.bounds.height
let screenWidth = UIScreen.main.bounds.width
let tv = SearchUsersTv(frame: CGRect(x: 0, y: 0, width: screenWidth, height: screenHeight))
tv.isUserInteractionEnabled = true
tv.bringSubview(toFront: tv)
tv.clipsToBounds = false
tv.tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cellId")
return tv
}()

Dismissing of search bar

I have some problem. I have UITableView and header of tableView is searchController with 1 red view (Inside of this view will be some icon).
After staring of search appears cancel button.
And now I press cancel button and search bar resize to full screen size and red view is disappear.
How to solve this problem?
Here is my headerView class:
lazy var searchController = UISearchController(searchResultsController: nil).then {
//return UISearchController().then {
$0.dimsBackgroundDuringPresentation = false
$0.searchBar.placeholder = "Искать по имени"
$0.searchBar.tintColor = .black
$0.searchBar.searchBarStyle = .minimal
$0.searchBar.backgroundColor = .white
UIBarButtonItem.appearance(whenContainedInInstancesOf: [UISearchBar.self]).setTitleTextAttributes([NSFontAttributeName : UIFont.appleSystemRegular(15)], for: .normal)
$0.searchBar.setValue("Отмена", forKey:"_cancelButtonText")
}
lazy var contentView: UIView = {
let view = UIView()
view.backgroundColor = .red
return view
}()
override init(frame: CGRect) {
super.init(frame: frame)
setupViews()
setupConstrains()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
fileprivate func setupViews() {
addSubview(contentView)
addSubview(searchController.searchBar)
}
func setupConstrains() {
searchController.searchBar.frame = CGRect(x: 0, y: 0, width: self.frame.width - 80, height: 44)
contentView.frame = CGRect(x: self.frame.width - 65, y: 0, width: 50, height: 44)
}
Remove searchcontroller and try to search only searchbar delegate.
func searchBar(searchBar: UISearchBar, textDidChange searchText: String) {
}

Resources