popOverView of dynamic size on clicking UitableView Cell - swift

How to create a popover of dynamic size on clicking UitableView cell in swift?
Should i use any tooltip frameworks? or just use apples PopOverViewController functionality?
It works fine in iPad with the below code. but in iphone it appears as a full screen view
Below code works fine and is the solution i got UIPopoverPresentationController on iPhone doesn't produce popover
by #tsik
class CommonViewController: UIViewController, UIPopoverPresentationControllerDelegate{
func adaptivePresentationStyle(
for controller: UIPresentationController,
traitCollection: UITraitCollection)
-> UIModalPresentationStyle {
return .none
}
func showPopover(){
let storyboard = UIStoryboard(name: "Pickers", bundle: nil)
let myViewController = UIViewController()
myViewController.preferredContentSize = CGSize(width: 320, height: 200)
myViewController.modalPresentationStyle = .popover
let popOver = myViewController.popoverPresentationController
popOver?.delegate = self
self.present(myViewController, animated: true, completion: nil)
popOver?.permittedArrowDirections = .init(rawValue: 0)
popOver?.sourceView = self.view
let rect = CGRect(
origin: CGPoint(x: self.view.frame.width/2, y: self.view.frame.height/2),
size: CGSize(width: 1, height: 1)
)
popOver?.sourceRect = rect
}

could you please check this code this is working fine in iphones in my case.
let popoverContent = self.storyboard!.instantiateViewController(withIdentifier: "PopOverViewController")
let ktagForLabel = 100
let popOverWidth = UIScreen.main.bounds.width - 40
if let label = popoverContent.view.viewWithTag(ktagForLabel) as? UILabel {
let descriptionText = self.subcategoryDetailViewModel.displayServiceDescriptionForPopOver(forIndex: sender.tag/10)
label.text = descriptionText
var estimatedTextHeight = descriptionText.heightWithConstrainedWidth(width: popOverWidth, font: UIFont.systemFont(ofSize: 15)) + 16
let nav = UINavigationController(rootViewController: popoverContent)
nav.isNavigationBarHidden = true
nav.modalPresentationStyle = UIModalPresentationStyle.popover
let popover = nav.popoverPresentationController!
estimatedTextHeight = estimatedTextHeight > 150 ? 150: estimatedTextHeight
popoverContent.preferredContentSize = CGSize(width: popOverWidth, height: estimatedTextHeight)
popover.delegate = self
popover.permittedArrowDirections = .up
popover.sourceView = sender
popover.sourceRect = sender.bounds
self.present(nav, animated: true, completion: nil)
}

Related

Present a Popover view from UIToolbar barButtonItem

Screenshot of the gap
I need to present a popover view from a UIBarbuttonItem in a UIToolbar. But there exists a gap between the popover view and the toolbar.
private func addToolbar() {
let toolBar = UIToolbar(frame: CGRect(x: 0, y: 0, width: view.frame.size.width, height: 50))
let item1 = UIBarButtonItem(image: UIImage(systemName: "pencil"), style: .plain, target: self, action: #selector(item1Pressed(_:)))
let item2 = UIBarButtonItem(image: UIImage(systemName: "house"), style: .plain, target: self, action: #selector(item2Pressed(_:)))
toolBar.sizeToFit()
toolBar.items = [item1, item2]
textField.inputAccessoryView = toolBar
}
class SearchViewController: UIViewController {
let searchBar = UISearchBar()
weak var viewControllerDelegate: SearchViewControllerDelegate?
override func viewDidLoad() {
super.viewDidLoad()
setupView()
setupSearchbar()
}
private func setupView() {
view.backgroundColor = .white
navigationController?.navigationBar.prefersLargeTitles = true
self.title = "Search"
}
private func setupSearchbar() {
searchBar.sizeToFit()
searchBar.placeholder = "Search test"
searchBar.showsCancelButton = true
searchBar.delegate = self
self.navigationItem.titleView = searchBar
}
}
I tried setting the sourceRect of the presented popover view, but the popover view doesn't move down below a certain point.
#objc private func item1Pressed(_ sender: UIBarButtonItem) {
let vc = SearchViewController()
vc.viewControllerDelegate = self
let navVC = UINavigationController(rootViewController: vc)
navVC.modalPresentationStyle = .popover
navVC.popoverPresentationController?.delegate = self
navVC.popoverPresentationController?.permittedArrowDirections = .any
navVC.preferredContentSize = CGSize(width: 500, height: 200)
navVC.popoverPresentationController?.sourceItem = sender
var location = CGPoint(x: 0, y: 0)
if let barItemView = sender.value(forKey: "view") as? UIView {
let barFrame = barItemView.frame
let rect = barItemView.convert(barFrame, to: view)
location = rect.origin
}
navVC.popoverPresentationController?.sourceRect = CGRect(x: location.x, y: location.y+100, width: 0, height: 0)
present(navVC, animated: true)
}

second vc is smaller that the initial vc

I got this problem on iPad after update yesterday: if I load the second view controller, it appears smaller that the initial one (see photos below). Interesting, that is happening only since my update to the new iOS on iPad. There is no such problem on iPhone: the both VCs have there the same size.
Here is the code:
import UIKit
class StartVC: UIViewController, ButtonDelegate {
var width = CGFloat()
var height = CGFloat()
override func viewDidLoad() {
super.viewDidLoad()
width = view.frame.width
height = view.frame.height
setTestBtn()
view.backgroundColor = UIColor.purple
}
func setTestBtn(){
let a = Button(frame: CGRect(x: 0,y: 0, width: width*0.2, height: width*0.2))
a.center = CGPoint(x: width*0.5, y: height*0.5)
a.backgroundColor = .cyan
a.delegate = self
a.setLabel()
a.label.text = "Go to the MainVC"
view.addSubview(a)
}
func buttonClicked(sender: Button) {
let vc = self.storyboard?.instantiateViewController(withIdentifier: "mainVC") as! MainVC
let transition = CATransition()
transition.duration = 2
transition.type = CATransitionType.push
transition.subtype = CATransitionSubtype.fromRight
view.window!.layer.add(transition, forKey: kCATransition)
vc.view.frame = view.bounds
self.present(vc, animated: true, completion: nil)
print("# ViewController func buttonClicked() OK!")
}
import UIKit
class MainVC: UIViewController, ButtonDelegate {
var width = CGFloat()
var height = CGFloat()
override func viewDidLoad() {
super.viewDidLoad()
width = view.frame.width
height = view.frame.height
setTestBtn()
view.backgroundColor = .red
}
func setTestBtn(){
let a = Button(frame: CGRect(x: 0,y: 0, width: width*0.2, height: width*0.2))
a.center = CGPoint(x: width*0.5, y: height*0.5)
a.backgroundColor = .orange
a.delegate = self
a.setLabel()
a.label.text = "Go to the StartVC"
view.addSubview(a)
}
func buttonClicked(sender: Button) {
let vc = self.storyboard?.instantiateViewController(withIdentifier: "startVC") as! StartVC
let transition = CATransition()
transition.duration = 2
transition.type = CATransitionType.push
transition.subtype = CATransitionSubtype.fromRight
view.window!.layer.add(transition, forKey: kCATransition)
vc.view.frame = view.bounds
self.present(vc, animated: true, completion: nil)
print("# ViewController func buttonClicked() OK!")
}
}
Since the release of iOS 13, the modal presentation style of View Controllers is chosen automatically by the system by default.
If you wish to counter this effect, this can help you.
vc.modalPresentationStyle = .overFullScreen
self.present(vc, animated: true, completion: nil)
Hope this helps!

Search bar with corner radius in swift

I want to create a view like the above image.it has a search bar with corner radius.but when i am trying to create, i am unable to make the search bar with corner radius.also i am unable to make the text field of the search bar with corner radius. i have writtenall my code in viewDidAppear method. It is ok or i have to write it in viewWillLayourSubview. so that i will be able to make the exact
same search bar like this image. also i want the seach icon to be placed slightly right.
My code is:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(true)
for subView in searchBar.subviews {
for subsubView in subView.subviews {
if let textField = subsubView as? UITextField {
var bounds: CGRect
var placeHolder = NSMutableAttributedString()
let Name = "Search"
placeHolder = NSMutableAttributedString(string:Name, attributes: [NSAttributedString.Key.font:UIFont(name: "Helvetica", size: 15.0)!])
placeHolder.addAttribute(NSAttributedString.Key.foregroundColor, value: UIColor.gray, range:NSRange(location:0,length:Name.count))
textField.attributedPlaceholder = placeHolder
if let leftView = textField.leftView as? UIImageView {
leftView.image = leftView.image?.withRenderingMode(.alwaysTemplate)
leftView.frame.size.width = 15.0
leftView.frame.size.height = 15.0
leftView.tintColor = UIColor.gray
}
textField.layer.cornerRadius = 50.0
bounds = textField.frame
bounds.size.width = searchBar.frame.width
bounds.size.height = searchBar.frame.height
textField.bounds = bounds
textField.borderStyle = UITextField.BorderStyle.roundedRect
searchBar.backgroundImage = UIImage()
textField.backgroundColor = UIColor.lightGray.withAlphaComponent(0.2)
searchBar.searchTextPositionAdjustment = UIOffset(horizontal: 5, vertical: 0)
}
}
}
}*
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(true)
for subView in searchBar.subviews {
if !subView.subviews.contains(where: { $0 as? UITextField != nil }) { continue }
guard let textField = subView.subviews.first(where: { $0 as? UITextField != nil }) as? UITextField else { return }
let placeholder = NSMutableAttributedString(
string: "Search",
attributes: [.font: UIFont(name: "Helvetica", size: 15.0)!,
.foregroundColor: UIColor.gray
])
textField.attributedPlaceholder = placeholder
textField.borderStyle = UITextField.BorderStyle.roundedRect
textField.layer.cornerRadius = textField.frame.size.height / 2
textField.layer.masksToBounds = true
textField.textColor = .white
textField.backgroundColor = .lightGray
}
searchBar.barTintColor = .white
searchBar.backgroundColor = .white
searchBar.searchTextPositionAdjustment = UIOffset(horizontal: 5, vertical: 0)
}
Doesn't look exactly like in the image that you linked, but actually fits better into the Apple design and works better than the code that you wrote.
For anything more sophisticated, I would advise to create a custom UISearchBar subclass.
Be aware of Apple's Human Interface Guidelines, so anything too crazy / different from default might not be accepted in the AppStore.

swift: after adding navigationController to viewController, tableView height is not fitting screen

after adding this codes to appDelegate inside didFinishLaunchingWithOptions function:
self.window = UIWindow(frame: UIScreen.main.bounds)
let mainView = PageViewController(coder: NSCoder())
let nav1 = UINavigationController(rootViewController: mainView!)
nav1.navigationBar.isTranslucent = false
self.window!.rootViewController = nav1
self.window?.makeKeyAndVisible()
tableView height is not looking good, some part of tableView(cells) not fitting screen
my codes for implementing tableView:
let myTableView = UITableView(frame: CGRect(x: 0, y: 40, width: screenSize.width, height: screenSize.height-40))
myTableView.bounces = false
myTableView.tableFooterView = UIView()
myTableView.register(UITableViewCell.self, forCellReuseIdentifier: "cellID")
myTableView.register(MyTableViewCell.self, forCellReuseIdentifier: "cellID2")
myTableView.dataSource = self
myTableView.delegate = self
for show all part of tableView in screen i have to change the first line above code to this:
let myTableView = UITableView(frame: CGRect(x: 0, y: 40, width: screenSize.width, height: screenSize.height-90))
why this is happening and what should i do to solve this problem thanks
Try something like this but don't forget to add myTableView as a subview before you set anchors:
myTableView.translatesAutoresizingMaskIntoConstraints = false
myTableView.leftAnchor.constraint(equalTo: myTableView.superview!.leftAnchor).isActive = true
myTableView.rightAnchor.constraint(equalTo: myTableView.superview!.rightAnchor).isActive = true
myTableView.topAnchor.constraint(equalTo: myTableView.superview!.topAnchor).isActive = true
myTableView.bottomAnchor.constraint(equalTo: myTableView.superview!.bottomAnchor).isActive = true

Swift, Add a navigation controller in custom activity indicator

My Custom Activity indicator is not overlapping Navigation controller.
Below is my code
func showActivityIndicator(uiView: UIView) {
container.frame = uiView.frame
container.center = uiView.center
container.backgroundColor = UIColorFromHex(0xffffff, alpha: 0.1)
var loadingView: UIView = UIView()
loadingView.frame = CGRectMake(0, 0, self.view.frame.width, self.view.frame.height)
loadingView.center = uiView.center
loadingView.backgroundColor = UIColorFromHex(0x444444, alpha: 0.5)
loadingView.clipsToBounds = true
loadingView.layer.cornerRadius = 10
var imageData = NSData(contentsOfURL: NSBundle.mainBundle()
.URLForResource("synch-loader", withExtension: "gif")!)
let try = UIImage.animatedImageWithData(imageData!)
var imageView = UIImageView(image: try)
imageView.center = uiView.center
imageView.frame = CGRect(x: uiView.frame.width/4, y: uiView.frame.height/2, width: 500, height: 15)
loadingView.addSubview(imageView)
container.addSubview(loadingView)
uiView.addSubview(container)
actInd.startAnimating()
}
func navigationHandling()
{
if self.navigationController != nil {
self.navigationController?.navigationBar.tintColor = utility.uicolorFromHex(0x70B420)
self.navigationController?.navigationBar.barTintColor = utility.uicolorFromHex(0x70B420)
self.navigationController?.navigationBarHidden = false
self.navigationItem.hidesBackButton = true
}
sortingBtn = UIBarButtonItem(image: sortingImg, style: UIBarButtonItemStyle.Done, target: self, action: Selector("sortingPressed:"))
menuBtn = UIBarButtonItem(image: menuImg, style: UIBarButtonItemStyle.Plain, target: self, action : nil)
sortingBtn.tintColor = UIColor.whiteColor()
menuBtn.tintColor = UIColor.whiteColor()
var buttons : NSArray = [menuBtn,sortingBtn]
self.navigationItem.rightBarButtonItems = buttons as [AnyObject]
self.navigationItem.setRightBarButtonItems([menuBtn,sortingBtn], animated: true)
networkLabel.hidden = true
}
I just want to overlap the view on navigation controller so that it don't looks ugly.
I appreciate help!
let appDelegate = UIApplication.sharedApplication().delegate as? AppDelegate
let window = appDelegate?.window
window.addSubview("yourActivityIndicator")
Here add the activity indicator to the window, or pass the window in as the view.
let appDelegate = UIApplication.sharedApplication().delegate as? AppDelegate
let window = appDelegate?.window
showActivityIndicator(window)
The uiView you're passing as parameter to this method
func showActivityIndicator(uiView: UIView)
is your ViewController's view or your UINavigationController's view?
Because if it's your UIViewController's view your custom loading will take it's size and origin, that is under your NavigationBar