In my Xcode project I have a view controller class
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var refreshButton: UIBarButtonItem!
var refreshUiButton = UIButton()
override func viewDidLoad() {
super.viewDidLoad()
refreshUiButton.setImage(#imageLiteral(resourceName: "refresh"), for: .normal)
refreshUiButton.imageView?.contentMode = UIViewContentMode.scaleAspectFit
refreshUiButton.addTarget(self, action: #selector(didRefreshClicked(_:)), for: .touchUpInside)
refreshButton.customView = refreshUiButton
}
and here what it looks like
The button covers segmented control in the middle of navigation panel.I have an extension for UIButton, because of it I want to use UIbutton as a custom view for UIBarButtonItem.
I want it to look like this
How can I organize that?
It’s seems that your button image has incorrect size. If I right you need sizes according Human Design. Or you can change tint color for system barButtonItem to black.
Related
I have created a simple UIViewController which contains a UITableView. When adding a tableHeaderView which includes a UIButton it seems not to be possible to change the button label using appearance settings. Other buttons outside the tableHeaderView are updated correctly.
Here the button which was placed directly in the ViewControllers view is updated correctly while the appearance settings seem not to effect the button inside the tableHeaderView.
class ListViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var tableHeaderView: UIView!
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
UILabel.appearance(whenContainedInInstancesOf: [TestButton.self]).font = UIFont.systemFont(ofSize: 30)
UILabel.appearance(whenContainedInInstancesOf: [TestButton.self]).textColor = .red
super.viewDidLoad()
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
tableView.tableHeaderView = tableHeaderView
}
...
}
class TestButton: UIButton {}
There are now other appearance settings in the project which might explain this. Moving the appearance settings to some other place, e.g. application:didFinishLaunchingWithOptions does not change the problem.
Is this a bug or am I missing something?
That will likely not be a suitable approach.
A UIButton does various things with its titleLabel - including changing the text color.
Trying to use UILabel.appearance(...) will not override the normal behavior.
You can see this by running your code as-is:
note that the view's TestButton does get the appearance
rotate the device so auto-layout re-positions the button
the appearance is lost
This is the same reason why we use:
button.setTitleColor(.red, for: .normal)
instead of:
button.titleLabel?.textColor = .red
You probably want to configure those properties in your custom TestButton class. Here's the basics:
class TestButton: UIButton {
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
func commonInit() {
setTitleColor(.red, for: .normal)
setTitleColor(.lightGray, for: .highlighted)
titleLabel?.font = UIFont.systemFont(ofSize: 30)
backgroundColor = .systemBlue
layer.cornerRadius = 6
}
}
I'm not sure this is what you are looking for or not.
Select button style to default, then
apply your theme or whatever property you want to change.
and one more thing instead of using
UILabel.appearance(whenContainedInInstancesOf: [TestButton.self]).font = UIFont.systemFont(ofSize: 30)
Use the button to change property.
TestButton.appearance().setTitleColor(.brown, for: .normal)
I cant create saperate custom popview.. so I have tried like below mentioned one of the answer
here is storyboard view hierarchy
popBG view background colour is black with alpha = 0.3
this is code:
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var popViewtop: UIView!
#IBOutlet weak var testTable: UITableView!
#IBOutlet weak var popView: UIView!
#IBOutlet weak var popBG: UIView!
override func viewDidLoad() {
super.viewDidLoad()
popViewtop.isHidden = true
}
#IBAction func testBtn(_ sender: Any) {
popViewtop.isHidden = false
}
#IBAction func btnPop(_ sender: Any) {
let viewController = self.storyboard?.instantiateViewController(withIdentifier: "NewZoomAddressViewController") as! NewZoomAddressViewController;
popViewtop.isHidden = true
self.navigationController?.pushViewController(viewController, animated: true);
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 10
}
}
now the tableview and button are not showing transperently.. only popbg and popview coming.. did i miss anything..
Actually i need like this: total backgroundview in some darkcolour and popupview heighlighted in white colour
if giving alpha value to view,
view's subView's alpha value changes, including popupView
if giving background color to view, including popupView
view's subView's alpha value does not change, including popupView
popupView is a subView of view,view's alpha value affects its subviews's alpha.
view.addSubview(popupView)
Your current structure:
RootView->Subviews //Changing RootView alpha effects Subviews.
The solution is that the popupView is not a subview of view , which you show color changing with
Need a container view to separate from popupView
// backgroundColorChangeContainerView add other views ( tableView ... )
view.addSubview(backgroundColorChangeContainerView)
view.addSubview(popupView)
Make your Popup view full screen ..which have background and have subview as popUp over that background ...so you dont need to change anything once you show or hide popup and its easy to implement... Full screen UIView having popUp UIView over it
You should have a view called it MainPopUpView ... in this view you will add two UIViews ...
Background View ... with black color with alpha 0.3
PopUpUI View ... which shows actual popup
-> backGround UIView full screen (with alpha 0.3)
MainPopUpView
-> popUpView short & centre and shows actual content
So MainPopUpView have two views ...
here is the hierarchy
other way to achieve like your final image.. custom pop controller avoids this situation
put your popupView in a custom viewController, then
#IBAction func addAddressBtn(_ sender: Any) {
present(PopupViewController(nibName: "PopupViewController", bundle: nil), animated: true) {}
}
The program is designed to have the screen toggle between black and white when the button is pressed. The problem is this is supposed to be accomplished with a button and not a switch. What is wrong with this code? When I run the program the background doesn't switch. Any suggestions on how to fix this issue?
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
// set the background color to white when opened
backgroundView.backgroundColor = .white
}
#IBOutlet weak var OnOffButton: UIButton!
#IBOutlet var backgroundView: UIView!
#IBAction func OnOff(_ sender: AnyObject) {
// write your code here
// code should change background color to black if it is white and vice versa.
if backgroundView.backgroundColor == .white {
backgroundView.backgroundColor = .black
} else {
backgroundView.backgroundColor = .white
}
}
}
I just created a brand new single view iOS app and it works perfectly.
In the new project, I added a UIButton to a the first scene in the storyboard and wired it to OnOff:
Note: you should NOT start functions with a capital letter by the way. It should be onOff:. Use Refactor to change this.
Then I dragged a UIView to that scene, right clicked on view and added a New Referencing Outlet, dragged from the + to the right up to the View Controller text on the left and assigned it to backgroundView.
It ran perfectly on the first try. It's possible that you have miswired the IBOutlet or IBAction. Add a breakpoint inside of your OnOff: function and see if it is triggered when you click on the button. If it is, make sure that the IBOutlet for backgroundView is properly hooked up by entering the following in the console:
po self.backgroundView
If it is nil, then it's not hooked up properly to the UIView.
Good luck!
I am in the process of updating my app to iOS10 with Swift 2.3 and Xcode 8 Beta 1 and I have found that there is a UITableViewHeaderFooterContentView which is blocking touches to the UIButton on my subclass of UITableViewHeaderFooterView.
On the Xcode 8 Beta 1 simulator the UIButton works on iOS9.3 but not iOS10.
1) Is there any documentation for this?
2) How can I ensure my UI elements are on top of the new Content View in iOS10? (or allow touches through the UITableHeaderFooterContentView)
Thanks!
Table Header
import UIKit
class TableHeader: UITableViewHeaderFooterView {
#IBOutlet weak var dayLabel: UILabel!
#IBOutlet weak var dateLabel: UILabel!
#IBOutlet weak var addNewEventButton: UIButton!
}
Code In View Controller
dateCell.addNewEventButton is the UIButton that is no longer receiving touches in iOS10
func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let tintColor = TintManager().getTintColour()
let dateCell:TableHeader = tableView.dequeueReusableHeaderFooterViewWithIdentifier("TableHeader") as! TableHeader
//dateCell.bringSubviewToFront(dateCell.addNewEventButton)
dateCell.dayLabel.text = Dates.day.uppercaseString
dateCell.dateLabel.text = Dates.date
dateCell.backgroundView = UIView(frame: dateCell.frame)
dateCell.backgroundView!.backgroundColor = tintColor
dateCell.dayLabel.textColor = UIColor.whiteColor()
dateCell.dateLabel.textColor = UIColor.whiteColor()
dateCell.addNewEventButton.backgroundColor = tintColor
dateCell.addNewEventButton.tag = section
dateCell.addNewEventButton.layer.cornerRadius = 20.0
if (savedEventView.superview === self.view) {
dateCell.addNewEventButton.removeTarget(nil, action: nil, forControlEvents: .AllEvents)
dateCell.addNewEventButton.addTarget(self, action: #selector(ViewController.userPressedAddButtonToInsertSavedEvent(_:)), forControlEvents:.TouchUpInside)
} else {
dateCell.addNewEventButton.removeTarget(nil, action: nil, forControlEvents: .AllEvents)
dateCell.addNewEventButton.addTarget(self, action: #selector(ViewController.userPressedAddNewEventOnTableViewHeader(_:)), forControlEvents:.TouchUpInside)
}
return dateCell
}
The offending view is in fact the contentView of the UITableViewHeaderFooterView (see the Apple Docs). So you should be able just to use sendSubview(toBack:) in order to stop it interfering with touches.
However, it seems that under iOS9 the UITableViewHeaderFooterView fails to correctly initialise the contentView if the view is loaded from a NIB. Although the contentView property is not optional, it is in fact nil, and you get a BAD ACCESS error if you try to access it. Nor can you set a value for contentView (either in code or as an outlet in IB) because it's a read only property (*). So the only solution I can think of is to use #available to conditionally include code to move the contentView to the back, if you are running on iOS 10 or newer. I would put the relevant code into your subclass:
override func awakeFromNib() {
if #available(iOS 10, *) {
self.sendSubview(toBack: contentView)
}
}
(*) Indulging in wild speculation, my guess is that Apple based the UITableViewHeaderFooterView code heavily on UITableViewCell. Since IB has UITableViewCells in its object library (and notice these include the cell's contentView), it can ensure that the cell's contentView is correctly instantiated. But since there is no UITableViewHeaderFooterView in the object library, there's no way to get the contentView loaded correctly. Looks like they fixed it in iOS10 by instantiating an empty contentView. Pity they didn't also add UITableViewHeaderFooterView to the library.
This is part of my code.
I want to show two UILabel and two UITextField on the background image: backgroundLogin.jpg .
import Foundation
import UIKit
class LoginViewController:UIViewController
{
override func viewDidLoad() {
super.viewDidLoad()
let BackGroundImage:UIImageView = UIImageView(frame: CGRectMake(0, 0, self.view.frame.width , self.view.frame.height))
let image: UIImage = UIImage(named: "backgroundLogin.jpg")!
BackGroundImage.image = image
self.view.addSubview(BackGroundImage)
//self.view.backgroundColor = UIColor(patternImage: UIImage(named: "backgroundLogin.jpg")!)
username.text = "User name"
password.text = "Password"
}
#IBOutlet weak var username: UILabel!
#IBOutlet weak var password: UILabel!
}
But when this code runs, it looks like:
I hope it can have two label on the image, but how to add that ?
Well like I stated in the comment you should try bring the UILabels to the front.
Since you are doing this programatically it can be done with bringSubviewToFront here is Apple's documentation on this and other UIView functionality you can use. Note: UILabel inherits from UIView so you can use these methods.
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIView_Class/#//apple_ref/doc/uid/TP40006816-CH3-SW46
The code:
override func viewDidLoad() {
super.viewDidLoad()
let BackGroundImage:UIImageView = UIImageView(frame: CGRectMake(0, 0, self.view.frame.width , self.view.frame.height))
let image: UIImage = UIImage(named: "backgroundLogin.jpg")!
BackGroundImage.image = image
self.view.addSubview(BackGroundImage)
//self.view.backgroundColor = UIColor(patternImage: UIImage(named: "backgroundLogin.jpg")!)
username.text = "User name"
password.text = "Password"
self.view.bringSubviewToFront(username)
self.view.bringSubviewToFront(password)
}
It seems you are adding the UIImageView in code and the UILabels on storyboard, then when you run the app the labels are behind the UIImageView and you can't see then.
Just check it adding BackGroundImage.hidden = true in viewDidLoad.
You can't add UILabels into a UIImageView. One solution would be add all views in code, 1st the image view and then the labels over it. Other option would be add all then in storyboard in the same order.
Like this:
You’re doing a lot here programmatically that you don’t need to do.
In Storyboard, add a UIImageView to a blank ViewController (you
can rename the view controller later if you wish)
With the new UIImageView selected, control-drag to create an outlet in your view controller named backgroundImage
With the UIImageView selected, choose the image you want it to display by going to the Attribute Inspector and from the dropdown
box, select your image. All images in your project should appear in
the dropdown box.
Now add a UILabel to the ViewController and control-drag to create an outlet in the corresponding code
In the viewDidLoad() method, bring the outlet to the front
All this requires code-wise is:
class ViewController: UIViewController {
#IBOutlet weak var backgroundImage: UIImageView!
#IBOutlet weak var username: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
self.view.bringSubviewToFront(username)
}
}