I am trying to expand the touch area of the filter button. When the green filter indicator appears it reduced the size. How can I fix this?
private func setupView() {
self.snp.makeConstraints { make in
make.height.equalTo(40)
}
addArrangedSubview(filtersOn)
addArrangedSubview(filterButton)
filtersOn.snp.makeConstraints { make in
make.centerY.equalTo(filterButton)
make.trailing.equalTo(filterButton.snp.leading).offset(50)
}
}
}
private func showFilterButton() {
guard let parent = parent as? MyDealersMasterViewController else { return }
let filterButton = FilterBarButtonItem(position: .right)
filterButton.filterButton.contentEdgeInsets = UIEdgeInsets(top: 60, left: 60, bottom: 60, right: 0)
filterButton.filterButton.addTarget(self, action: #selector(filterDealerList), for: .touchUpInside)
filterButton.backgroundColor = .red
parent.navigationItem.rightBarButtonItem?.customView = filterButton
}
Related
I need to change alpha value of the button in another class. But the problem is button created as "lazy var" so I can not change that value.
lazy var middleButton: UIButton = {
let button = UIButton(type: .custom)
button.frame.size = CGSize(width: 56, height: 56)
button.layer.cornerRadius = button.frame.width / 2
button.layer.masksToBounds = true
button.backgroundColor = .white
button.setImage(UIImage(named: "iconBasket"), for: .normal)
button.contentMode = .center
button.imageView?.contentMode = .scaleAspectFit
button.imageEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
button.addTarget(self, action: #selector(btnBasketClicked))
addSubview(button)
return button
}()
I want this button's alpha as 0.2 when view is scrolling. Here is the code
extension ProductListView: UIScrollViewDelegate{
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if scrollView.panGestureRecognizer.translation(in: scrollView).y < 0{
// alpha = 0.2
MyTabBar.shared.scrollDown()
}
else{
// alpha = 1.0
MyTabBar.shared.scrollUp()
}
}
}
func scrollDown(){
middleButton.alpha = 0.2
}
I've tried lots of way but doesn't work. Calling "addSubView()" function in "layoutSubviews()" solve my problem but this causes another problem which my function "basketButtonClicked()" are not called. I used Delegate pattern and here it is.
protocol BasketButtonDelegate: class {
func basketButtonClicked()
}
#objc private func btnBasketClicked(_ sender: UIButton!){
delegate?.basketButtonClicked()
}
override func layoutSubviews() {
super.layoutSubviews()
addSubview(middleButton)
}
When I call "addSubView" function in "layoutSubviews()", "basketbuttonClicked" never called.
extension TabCoordinator : BasketButtonDelegate
{
func basketButtonClicked(){
log.debug("basketButtonClicked")
let coor = CartCoordinator(navigationController, hidesBar: true)
childCoordinators.append(coor)
coor.start()
}
}
(I assigned delegate so the problem is not about it.)
A bit complicated but I hope we can figure it out.
You need to add protocol to your MyTabBar class . It should be like this
class MyTabBar {
static var shared = MyTabBar()
weak var delegate : abc?
func scrollDown(){
delegate?.xyz()
}
}
protocol abc : AnyObject {
func xyz()
}
And in your class
class btnView : UIView , abc{
lazy var middleButton: UIButton = {
let button = UIButton(type: .custom)
button.frame.size = CGSize(width: 56, height: 56)
button.layer.cornerRadius = button.frame.width / 2
button.layer.masksToBounds = true
button.backgroundColor = .red
button.contentMode = .center
button.imageView?.contentMode = .scaleAspectFit
button.imageEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
button.addTarget(self, action: #selector(btnBasketClicked), for: .touchUpInside)
return button
}()
required init?(coder: NSCoder) {
super.init(coder: coder)
}
override init(frame: CGRect) {
super.init(frame: frame)
}
#objc func btnBasketClicked(){
print("Im here")
}
func addMiddleButton(){
self.addSubview(middleButton)
}
func alphaaa(){
self.middleButton.alpha = 0.2
}
func xyz() {
self.alphaaa()
}
}
Last , in your ProductListView create and instance of your view , or if you add with autolayout just call 2. function in your viewDidLoad
var viewwww = btnView(frame: CGRect(x: 10, y: 10, width: 100, height: 100))
viewwww.addMiddleButton() // call to add btn to custom view
and extension
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if scrollView.panGestureRecognizer.translation(in: scrollView).y < 0{
// alpha = 0.2
MyTabBar.shared.delegate = viewwww
MyTabBar.shared.scrollDown()
}
else{
// alpha = 1.0
MyTabBar.shared.scrollUp()
}
}
I have a UICollectionViewCell that contains a UIButton.
When tapping the button in a cell, I want to toggle the selected state.
This works to an extent, the bug I am seeing is, clicking in 1 cell toggles the state in another cell also.
import UIKit
import RxSwift
class PersonaliseYourAppsListCell: BaseCollectionViewCell<Launcher> {
let toggleSelectedTrigger = PublishSubject<String>()
private let disposeBag = DisposeBag()
override init(frame: CGRect) {
super.init(frame: frame)
configureSubviews()
}
required init?(coder: NSCoder) {
return nil
}
override func render(with model: Launcher?) {
guard let model = model else { return }
title.text = model.name
icon.image = model.icon
toggleButton.rx.tap.bind { [weak self] in
self?.toggleButton.isSelected.toggle()
self?.toggleSelectedTrigger.onNext(model.id)
}.disposed(by: disposeBag)
if let status = model.status {
toggleButton.isSelected = model.selected ?? false
toggleButton.isUserInteractionEnabled = status != .forced
[title, icon, toggleButton].forEach {
$0.alpha = status == .forced ? 0.6 : 1
}
if status == .forced {
addSubviews(enforcedLabel)
enforcedLabel.position(top: title.bottomAnchor, leading: title.leadingAnchor, withPadding: .zero)
}
}
}
override func prepareForReuse() {
super.prepareForReuse()
enforcedLabel.removeFromSuperview()
}
// MARK:- UI Elements
private func configureSubviews() {
addSubviews(icon, title, toggleButton, separatorView)
icon
.isCenteredY()
.position(
leading: leadingAnchor,
withPadding: .init(top: 0, left: 16, bottom: 0, right: 4)
)
title
.isCenteredY()
.position(
leading: icon.trailingAnchor, trailing: toggleButton.leadingAnchor,
withPadding: .init(top: 0, left: 8, bottom: 0, right: 8)
)
toggleButton
.isCenteredY()
.withSize(.init(width: 44, height: 44))
.position(trailing: trailingAnchor, withPadding: .init(top: 0, left: 0, bottom: 0, right: 16))
separatorView
.isCenteredX()
.withSize(.init(width: frame.width - 48, height: 1))
.position(bottom: bottomAnchor)
}
private lazy var icon: UIImageView = {
let iv = UIImageView(frame: .zero)
iv.contentMode = .scaleAspectFit
[iv.widthAnchor, iv.heightAnchor].forEach { $0.constraint(equalToConstant: 64).isActive = true }
return iv
}()
private lazy var title: UILabel = {
let label = UILabel(frame: .zero)
label.font = .systemFont(ofSize: 20)
label.textAlignment = .left
label.numberOfLines = 2
label.textColor = .usingHex("444444")
return label
}()
private lazy var toggleButton: CheckBoxButton = {
let button = CheckBoxButton(type: .custom)
return button
}()
private lazy var enforcedLabel: UILabel = {
let label = UILabel(frame: .zero)
label.text = "This app cannot be removed"
label.font = .systemFont(ofSize: 12)
label.textColor = .lightGray
return label
}()
private lazy var separatorView: UIView = {
let view = UIView()
view.backgroundColor = UIColor(white: 0.3, alpha: 0.1)
return view
}()
}
My CollectionView is setup as follows:
override func viewDidLoad() {
super.viewDidLoad()
presenter?.viewIsReady.onNext(())
presenter?.data.bind(to: customView.collectionView.rx.items) { [weak self] (cv, row, item) -> UICollectionViewCell in
let cell = cv.dequeueReusableCell(withClass: PersonaliseYourAppsListCell.self, for: .init(row: row, section: 0))
cell.render(with: item)
if let self = self, let presenter = self.presenter {
cell.toggleSelectedTrigger.bind(to: presenter.updateUserAppsTrigger).disposed(by: self.disposeBag)
}
return cell
}.disposed(by: disposeBag)
customView.configureLayout()
}
EDIT
I've noticed if I do not make the api call and just let the buttons state toggle, the bug does not exist. I wonder if the response is reloading the collection view and due to re use the wrong button state is being updated.
EDIT 2
If I trigger the API call by selecting the cell instead of the button everything works, However I would like this to happen on button click.
I suspect still this is something todo with button state.
As Subramanian Mariappan suggests, it might be because of cells being reused. In your render method you subscribe to button tap and you never actually stop observing. Replace:
private let disposeBag = DisposeBag()
with:
private var disposeBag = DisposeBag()
and in func prepareForReuse() add creation of a new disposeBag (which will release the old one by the way).
override func prepareForReuse() {
super.prepareForReuse()
enforcedLabel.removeFromSuperview()
disposeBag = DisposeBag()
}
My problem is that UITableView lags quite a lot while scrolling.
This is what I am trying to achieve
Starting from the top I have a simple section header with only one checkbox and one UILabel. Under this header, you can see a custom cell with only one UILabel aligned to the center. This custom cell works like another header for the data that would be shown below (Basically a 3D array). Under these "headers" are custom cells that contain one multiline UILabel and under this label is a container for a variable amount of lines containing a checkbox and an UILabel. On the right side of the cell is also a button (blue/white arrow).
So this means the content is shown like this:
Section header (containing day and date)
Custom UITableViewCell = header (containing some header information)
Custom UITableViewCell (containing data to be shown)
Here is my code:
cellForRowAt:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let (isHeader, headerNumber, semiResult) = checkIfIsHeader(section: indexPath.section, row: indexPath.row)
let row = indexPath.row
if isHeader {
let chod = objednavkaDny[indexPath.section].chody[headerNumber+1]
let cell = tableView.dequeueReusableCell(withIdentifier: cellHeaderReuseIdentifier, for: indexPath) as! ObjednavkyHeaderTableViewCell
cell.titleLabel.text = chod.popisPoradiJidla
cell.selectionStyle = .none
return cell
}else{
let chod = objednavkaDny[indexPath.section].chody[headerNumber]
let cell = tableView.dequeueReusableCell(withIdentifier: reuseIdentifier, for: indexPath) as! ObjednavkyTableViewCell
cell.updateData(objednavka: chod.objednavky[row-semiResult], canSetAmount: self.typDialogu == 3)
return cell
}
}
checkIfIsHeader:
func checkIfIsHeader(section: Int, row: Int) -> (Bool, Int, Int){
if let cachedResult = checkIfHeaderCache[section]?[row] {
return (cachedResult[0] == 1, cachedResult[1], cachedResult[2])
}
var isHeader = false
var semiResult = 0
var headerNumber = -1
for (index, chod) in objednavkaDny[section].chody.enumerated() {
let sum = chod.objednavky.count
if row == semiResult {
isHeader = true
break
}else if row < semiResult {
semiResult -= objednavkaDny[section].chody[index-1].objednavky.count
break
}else {
headerNumber += 1
semiResult += 1
if index != objednavkaDny[section].chody.count - 1 {
semiResult += sum
}
}
}
checkIfHeaderCache[section] = [Int:[Int]]()
checkIfHeaderCache[section]![row] = [isHeader ? 1 : 0, headerNumber, semiResult]
return (isHeader, headerNumber, semiResult)
}
and the main cell that shows the data:
class ObjednavkyTableViewCell: UITableViewCell {
lazy var numberTextField: ObjednavkyTextField = {
let textField = ObjednavkyTextField()
textField.translatesAutoresizingMaskIntoConstraints = false
return textField
}()
let mealLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.textColor = .black
label.textAlignment = .left
label.font = UIFont(name: ".SFUIText", size: 15)
label.numberOfLines = 0
label.backgroundColor = .white
label.isOpaque = true
return label
}()
lazy var detailsButton: UIButton = {
let button = UIButton(type: .custom)
button.translatesAutoresizingMaskIntoConstraints = false
button.setImage(UIImage(named: "arrow-right")?.withRenderingMode(.alwaysTemplate), for: .normal)
button.imageView?.tintColor = UIColor.custom.blue.classicBlue
button.imageView?.contentMode = .scaleAspectFit
button.contentHorizontalAlignment = .right
button.imageEdgeInsets = UIEdgeInsetsMake(10, 0, 10, 0)
button.addTarget(self, action: #selector(detailsButtonPressed), for: .touchUpInside)
button.backgroundColor = .white
button.isOpaque = true
return button
}()
let pricesContainerView: UIView = {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
view.backgroundColor = .white
view.isOpaque = true
return view
}()
var canSetAmount = false {
didSet {
canSetAmount ? showNumberTextField() : hideNumberTextField()
}
}
var shouldShowPrices = false {
didSet {
shouldShowPrices ? showPricesContainerView() : hidePricesContainerView()
}
}
var pricesContainerHeight: CGFloat = 0
private let priceViewHeight: CGFloat = 30
var mealLabelLeadingConstraint: NSLayoutConstraint?
var mealLabelBottomConstraint: NSLayoutConstraint?
var pricesContainerViewHeightConstraint: NSLayoutConstraint?
var pricesContainerViewBottomConstraint: NSLayoutConstraint?
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
self.selectionStyle = .none
setupView()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
#objc func detailsButtonPressed() {
}
func updateData(objednavka: Objednavka, canSetAmount: Bool) {
self.canSetAmount = canSetAmount
if let popisJidla = objednavka.popisJidla, popisJidla != "", popisJidla != " " {
self.mealLabel.text = popisJidla
}else{
self.mealLabel.text = objednavka.nazevJidelnicku
}
if objednavka.objects.count > 1 {
shouldShowPrices = true
setPricesStackView(with: objednavka.objects)
checkIfSelected(objects: objednavka.objects)
}else{
shouldShowPrices = false
self.numberTextField.text = String(objednavka.objects[0].pocet)
//setSelected(objednavka.objects[0].pocet > 0, animated: false)
objednavka.objects[0].pocet > 0 ? setSelectedStyle() : setDeselectedStyle()
}
}
//---------------
func checkIfSelected(objects: [ObjednavkaObject]) {
var didChangeSelection = false
for object in objects { // Checks wether cell should be selected or not
if object.pocet > 0 {
setSelected(true, animated: false)
setSelectedStyle()
didChangeSelection = true
break
}
}
if !didChangeSelection {
setSelected(false, animated: false)
setDeselectedStyle()
}
}
//--------------
func showNumberTextField() {
numberTextField.isHidden = false
mealLabelLeadingConstraint?.isActive = false
mealLabelLeadingConstraint = mealLabel.leadingAnchor.constraint(equalTo: numberTextField.trailingAnchor, constant: 10)
mealLabelLeadingConstraint?.isActive = true
}
func hideNumberTextField() {
numberTextField.isHidden = true
mealLabelLeadingConstraint?.isActive = false
mealLabelLeadingConstraint = mealLabel.leadingAnchor.constraint(equalTo: readableContentGuide.leadingAnchor, constant: 0)
mealLabelLeadingConstraint?.isActive = true
}
func showPricesContainerView() {
hideNumberTextField()
pricesContainerView.isHidden = false
mealLabelBottomConstraint?.isActive = false
pricesContainerViewBottomConstraint?.isActive = true
}
func hidePricesContainerView() {
pricesContainerView.isHidden = true
pricesContainerViewBottomConstraint?.isActive = false
mealLabelBottomConstraint?.isActive = true
}
//--------------
func setSelectedStyle() {
self.backgroundColor = UIColor.custom.blue.classicBlue
mealLabel.textColor = .white
mealLabel.backgroundColor = UIColor.custom.blue.classicBlue
for subview in pricesContainerView.subviews where subview is ObjednavkyPriceView {
let priceView = (subview as! ObjednavkyPriceView)
priceView.titleLabel.textColor = .white
priceView.checkBox.backgroundColor = UIColor.custom.blue.classicBlue
priceView.titleLabel.backgroundColor = UIColor.custom.blue.classicBlue
priceView.backgroundColor = UIColor.custom.blue.classicBlue
}
pricesContainerView.backgroundColor = UIColor.custom.blue.classicBlue
detailsButton.imageView?.tintColor = .white
detailsButton.backgroundColor = UIColor.custom.blue.classicBlue
}
func setDeselectedStyle() {
self.backgroundColor = .white
mealLabel.textColor = .black
mealLabel.backgroundColor = .white
for subview in pricesContainerView.subviews where subview is ObjednavkyPriceView {
let priceView = (subview as! ObjednavkyPriceView)
priceView.titleLabel.textColor = .black
priceView.checkBox.backgroundColor = .white
priceView.titleLabel.backgroundColor = .white
priceView.backgroundColor = .white
}
pricesContainerView.backgroundColor = .white
detailsButton.imageView?.tintColor = UIColor.custom.blue.classicBlue
detailsButton.backgroundColor = .white
}
//-----------------
func setPricesStackView(with objects: [ObjednavkaObject]) {
let subviews = pricesContainerView.subviews
var subviewsToDelete = subviews.count
for (index, object) in objects.enumerated() {
subviewsToDelete -= 1
if subviews.count - 1 >= index {
let priceView = subviews[index] as! ObjednavkyPriceView
priceView.titleLabel.text = object.popisProduktu // + " " + NSNumber(value: object.cena).getFormattedString(currencySymbol: "Kč") // TODO: currencySymbol
priceView.canSetAmount = canSetAmount
priceView.count = object.pocet
priceView.canOrder = (object.nelzeObj == nil || object.nelzeObj == "")
}else {
let priceView = ObjednavkyPriceView(frame: CGRect(x: 0, y: CGFloat(index) * priceViewHeight + CGFloat(index * 5), width: pricesContainerView.frame.width, height: priceViewHeight))
pricesContainerView.addSubview(priceView)
priceView.titleLabel.text = object.popisProduktu // + " " + NSNumber(value: object.cena).getFormattedString(currencySymbol: "Kč") // TODO: currencySymbol
priceView.numberTextField.delegate = self
priceView.canSetAmount = canSetAmount
priceView.canOrder = (object.nelzeObj == nil || object.nelzeObj == "")
priceView.count = object.pocet
pricesContainerHeight += ((index == 0) ? 30 : 35)
}
}
if subviewsToDelete > 0 { // Deletes unwanted subviews
for _ in 0..<subviewsToDelete {
pricesContainerView.subviews.last?.removeFromSuperview()
pricesContainerHeight -= pricesContainerHeight + 5
}
}
if pricesContainerHeight < 0 {
pricesContainerHeight = 0
}
pricesContainerViewHeightConstraint?.constant = pricesContainerHeight
}
func setupView() {
self.layer.shouldRasterize = true
self.layer.rasterizationScale = UIScreen.main.scale
self.backgroundColor = .white
contentView.addSubview(numberTextField)
contentView.addSubview(mealLabel)
contentView.addSubview(detailsButton)
contentView.addSubview(pricesContainerView)
setupConstraints()
}
func setupConstraints() {
numberTextField.anchor(leading: readableContentGuide.leadingAnchor, size: CGSize(width: 30, height: 30))
numberTextField.centerYAnchor.constraint(equalTo: mealLabel.centerYAnchor).isActive = true
detailsButton.anchor(trailing: readableContentGuide.trailingAnchor, size: CGSize(width: 30, height: 30))
detailsButton.centerYAnchor.constraint(equalTo: contentView.centerYAnchor).isActive = true
mealLabel.anchor(top: contentView.topAnchor, trailing: detailsButton.leadingAnchor, padding: .init(top: 10, left: 0, bottom: 0, right: -10))
mealLabelBottomConstraint = mealLabel.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -10)
mealLabelBottomConstraint?.priority = UILayoutPriority(rawValue: 999)
pricesContainerView.anchor(top: mealLabel.bottomAnchor, leading: readableContentGuide.leadingAnchor, trailing: detailsButton.leadingAnchor, padding: .init(top: 10, left: 0, bottom: 0, right: -10))
pricesContainerViewBottomConstraint = pricesContainerView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -10)
pricesContainerViewBottomConstraint?.priority = UILayoutPriority(rawValue: 999)
pricesContainerViewHeightConstraint = pricesContainerView.heightAnchor.constraint(equalToConstant: 0)
pricesContainerViewHeightConstraint?.priority = UILayoutPriority(rawValue: 999)
pricesContainerViewHeightConstraint?.isActive = true
}
}
To conclude how it is done:
tableView.rowHeight is set to UITableViewAutomaticDymension
inside cellForRowAt I get the data from an array and give it to the
cell
all the cells are set up in code using constraints
all the views have set isOpaque = true
heights of the cells are cached
cells are set to rasterize
I also noticed that it lags at certain scroll levels and that sometimes it works just fine and sometimes it lags a lot.
Despite all of the optimization I have done, the tableView still lags while scrolling.
Here is a screenshot from Instruments
Any tip how to improve the scrolling performance is highly appreciated!
(I might have forgotten to include some code/information so feel free to ask me in the comments.)
I can't tell you where the lag happens exactly but when we are talking about lagging during scrolling, it's related to your cellForRowAt delegate method. What happends is that too many things are going on within this method and it's called for every cells that are displaying & going to display. I see that your are trying to cache the result by checkIfHeaderCache but still, there is a for loop at the very beginning to determine header cell.
Suggestions:
I don't know where you get data (objednavkaDny) from but right after you get the data, do a full loop through and determin cell type one by one, and save the result some where base on your design. During this loading time, you can show some loading message on the screen. Then, within the cellForRow method, you should be just simply using things like
if (isHeader) {
render header cell
} else {
render other cell
}
Bottom line:
cellForRow method is not designed to handle heavy calculations, and it will slow down the scrolling if you do so. This method is for assigning values to the cached table view cell only and that's the only thing it is good at.
I want both tabs(Hello World, Tab) equal width of controller width . I put the complete code of my tabs. if anyone have suggestion for it. plz give suggestion.i am waiting. Comment & Answer Fast.
import UIKit
import CarbonKit
class ViewController: UIViewController, CarbonTabSwipeNavigationDelegate {
func generateImage(for view: UIView) -> UIImage? {
defer {
UIGraphicsEndImageContext()
}
UIGraphicsBeginImageContextWithOptions(view.bounds.size, false, UIScreen.main.scale)
if let context = UIGraphicsGetCurrentContext() {
view.layer.render(in: context)
return UIGraphicsGetImageFromCurrentImageContext()
}
return nil
}
var iconWithTextImage: UIImage {
let button = UIButton()
let icon = UIImage(named: "home")
button.setImage(icon, for: .normal)
button.setTitle("Home", for: .normal)
button.setTitleColor(UIColor.blue, for: .normal)
button.titleLabel?.font = UIFont.systemFont(ofSize: 15)
button.contentEdgeInsets = UIEdgeInsets(top: 0, left: 20, bottom: 0, right: 10)
button.imageEdgeInsets = UIEdgeInsets(top: 0, left: -10, bottom: 0, right: 10)
button.sizeToFit()
return generateImage(for: button) ?? UIImage()
}
override func viewDidLoad() {
super.viewDidLoad()
let tabSwipe = CarbonTabSwipeNavigation(items: ["HELLO WORLD", "Tab"], delegate: self)
tabSwipe.setTabExtraWidth(40)
tabSwipe.insert(intoRootViewController: self)
}
func carbonTabSwipeNavigation(_ carbonTabSwipeNavigation: CarbonTabSwipeNavigation, viewControllerAt index: UInt) -> UIViewController {
guard let storyboard = storyboard else { return UIViewController() }
if index == 0 {
return storyboard.instantiateViewController(withIdentifier: "FirstViewController")
}
return storyboard.instantiateViewController(withIdentifier: "SecondTableViewController")
}
}
This helps you.
First of all set carbonSegmentControl frame to Screen equal Width like this.
var frameRect: CGRect = (carbonTabSwipeNavigation.carbonSegmentedControl?.frame)!
frameRect.size.width = UIScreen.main.bounds.size.width
carbonTabSwipeNavigation.carbonSegmentedControl?.frame = frameRect
After that write this line for equal width.
carbonTabSwipeNavigation.carbonSegmentedControl?.apportionsSegmentWidthsByContent = false
1. Before Equal Width
2. After Equal Width
I have done code like this but it's open QLPreviewController but
Share button was not disabled. I have tried different things but it's
not worked.
- Or You Can Suggest me any different Preview Controller in which i can Disable Share button.
qlViewController = QLPreviewController()
qlViewController.navigationItem.rightBarButtonItem = nil
qlViewController.delegate = self
qlViewController.dataSource = self
func numberOfPreviewItemsInPreviewController(controller: QLPreviewController) -> Int {
return 1
}
func previewController(controller: QLPreviewController, previewItemAtIndex index: Int) -> QLPreviewItem {
controller.navigationItem.rightBarButtonItem = nil
return fileUrlToOpen
}
Tested on iOS 15, may change with next updates.
QLPreviewController now embeds a UINavigationController which then has a root controller with a standard navigationItem that we can tweak.
guard let navigationItem = (aQLPreviewController.children.first as? UINavigationController)?.viewControllers.first?.navigationItem else
{
// Not iOS 15 or the QLPreviewController implementation has changed
return
}
// Do whatever you want with the navigationItem
navigationItem.rightBarButtonItem?.isEnabled = false
// or navigationItem.rightBarButtonItem = nil
UPD: This DOESN'T work anymore
There is an example of how to hide the right share button
final class AttachmentQuickLookVC: QLPreviewController {
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
self.navigationItem.rightBarButtonItems = [UIBarButtonItem]()
}
}
Also, u can do something like this if u want to customize back button:
final class AttachmentQuickLookVC: QLPreviewController {
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
let backButton = UIButton(frame: CGRect(x: 0, y: 0, width: 100, height: 35))
backButton.contentEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
backButton.contentHorizontalAlignment = .left
backButton.setImage(UIImage(named: "ic_back"), for: .normal)
let barButton = UIBarButtonItem(customView: backButton)
self.navigationItem.leftBarButtonItems = [barButton]
self.navigationItem.hidesBackButton = true
}
}