since iOS15 a strange top gap started to appear
after research i found out that
if #available(iOS 15, *) {
tableView.sectionHeaderTopPadding = 0
}
should solve the issue
however this works only for plain style table (UITableView.Style.plain), but my table is grouped and it looks like this property is taking no effect on GROUPED style (UITableView.Style.grouped)
is this a bug? how to remove the gap on grouped table?
According to the What's new in UIKit video from WWDC2021, top padding seems to have been added only to the plain style of UITableView.
Here's the part that mentions it
We have a new appearance for headers in iOS 15. For plain lists, section headers now display seamlessly in line with the content, and only display a visible background material when becoming pinned to the top as you scroll down. In addition, there's new padding inserted above each section header to visually separate the sections with this new design.
You should use this plain style in conjunction with index bars for fast scrubbing when list content is long as demonstrated in the Contacts app.
https://developer.apple.com/videos/play/wwdc2021/10059/?time=438
You can try this (this worked for me for grouped/insetGrouped)
if #available(iOS 15.0, *) {
UITableView.appearance().sectionHeaderTopPadding = 0
let tableHeaderView = UIView()
tableHeaderView.translatesAutoresizingMaskIntoConstraints = false
tableHeaderView.heightAnchor.constraint(equalToConstant: 5).isActive = true
UITableView.appearance().tableHeaderView = tableHeaderView
} else {
// Fallback on earlier versions
}
Related
I have a couple of UIKit pop-up menu buttons with identical menu items on the same screen in a Swift app. The buttons are built by calling a function that uses an array of strings to create the list of menu items.
The problem is that depending on the button's vertical position on the screen, the menu items may appear in the order specified by the function, or reversed. If the button is in the upper half of the screen, the menu items are listed in the correct order. If the button is in the lower half of the screen the menu items are listed in reverse order.
I would prefer the menu items to appear in the same order regardless of the button's position on the screen. I could check the button location and have the menu creation function reverse the order, but that seems kind of clunky. I am hoping there's a cleaner way to override this behaviour.
The code and array used to create the button menus:
let buttonMenuItems = ["Spring","Summer","Autumn","Winter"]
func createAttributeMenu(menuNumber: Int)->UIMenu {
var menuActions: [UIAction] = []
for attribute in buttonMenuItems {
let item = UIAction(title: attribute) { action in
self.updateMenu(menuID: menuNumber, selected: attribute)
}
menuActions.append(item)
}
return UIMenu(title: "", children: menuActions)
}
The result is this:
Versions I'm using now in testing: Xcode 14.1, iOS 16.1, but I have seen this behaviour on earlier versions as well. (back to iOS 14.x)
Starting with iOS 16, there is a .preferredMenuElementOrder property that can be set on the button:
case automatic
A constant that allows the system to choose an ordering strategy according to the current context.
case priority
A constant that displays menu elements according to their priority.
case fixed
A constant that displays menu elements in a fixed order.
Best I can tell (as with many Apple definitions), there is no difference between .automatic and .priority.
From the .priority docs page:
Discussion
This ordering strategy displays the first menu element in the UIMenu closest to the location of the user interaction.
So, we get "reversed" order based on the position of the menu relative to the button.
To keep your defined order:
buttonNearTop.menu = createAttributeMenu(menuNumber: 1)
buttonNearBottom.menu = createAttributeMenu(menuNumber: 2)
if #available(iOS 16.0, *) {
buttonNearBottom.preferredMenuElementOrder = .fixed
buttonNearTop.preferredMenuElementOrder = .fixed
} else {
// out of luck... you get Apple's "priority" ordering
}
The new UICollectionViewCompositionalLayout introduced in iOS 13 have a property named decorationItems for adding decoration items conveniently, which you could use to add a background for the section.
let section = NSCollectionLayoutSection(group: group)
section.decorationItems = [
NSCollectionLayoutDecorationItem.background(elementKind:"your identifier")
]
Which is working fine for the full section.
what I want is to add a decoration view only on items since I want
rounded background only for section items excluding header and footer.
could anyone help?
You can use a property contentInsets on NSCollectionLayoutDecorationItem in order to exclude header and footer
I've read all the articles about supporting dynamic text size, but my problem is that I have a view consisting of shapes and some text. I needed to hard code the height of this view, so when a user uses a larger text size the text overlaps the shapes. What I would like to do is detect when a larger text size is used and increase the hard coded height of the view.
There is an environment value for that:
#Environment(\.sizeCategory) var sizeCategory
With that, you can do stuff like:
if sizeCategory > ContentSizeCategory.large {
// views for large text
} else {
// views for regular/small text
}
You should also check out the #ScaledMetric property wrapper, which will auto-scale your var based on the user’s text size:
#ScaledMetric var height: CGFloat = 100
Here's a nice summary of both: https://swiftwithmajid.com/2019/10/09/dynamic-type-in-swiftui/
I have a programatically created NSTableView that I am adding new columns to:
func createColumnsOnTable(table : NSTableView, columnNames: String[], hideColumns: String[])
{
for columnNum in 0 .. 2
{
let columnName = columnNames[columnNum]
var newTableColumn = NSTableColumn()
var newHeaderCell = NSTableHeaderCell()
newTableColumn.setHeaderCell(newHeaderCell)
newTableColumn.setIdentifier(columnName.lowercaseString)
newHeaderCell.setTitle(columnName)
newTableColumn.setEditable(true)
newTableColumn.sizeToFit()
newTableColumn.setResizingMask(NSTableColumnUserResizingMask)
//newHeaderCell.drawSortIndicatorWithFrame(table.headerView().frame(), inView: table.headerView(), ascending: true, priority: 0)
if isInSet(columnName, valueArray: hideColumns)
{
newTableColumn.setHidden(true)
}
var sortDescriptor = NSSortDescriptor(key: newTableColumn.identifier(), ascending: true, selector: "compare")
newTableColumn.setSortDescriptorPrototype(sortDescriptor)
table.addTableColumn(newTableColumn)
}
}
My problem is the new columns display fine and look OK but the vertical gridline is not lined up with the divider in the header. In addition as the divider is dragged to make the column wider the column gets wider but the alignment gets even more skewed. I'm not sure how to get them to stay lined up when resizing the column or how to even get them to start off lined up. When I use a tableview created in IB I don't have this problem so I know I'm missing something but just can't find what.
Thanks for any help you can provide.
I discovered the reason. When trying to work out why I had no scroll bars I had added a setBoundsSize setting on the contentView of the scrollView containing the tableView. Once I got rid of that line all started behaving as normal. Just in case anyone else runs into this issue (however unlikely that may be) the line I removed was:
newScrollView.contentView().setBoundsSize(newScrollView.bounds().size)
I'm having a bit of trouble with the layout of the GUI in Titanium Mobile (iPhone). Is there a guide/article somewhere that explains how height/width/positioning/scrolling/etc. works in Titanium Mobile?
Right now I'm stuck on two problems:
I want a scrollable window with an ImageView in the top part, and a TableView beneath it. They should both scroll together. I tried adding them both to a ScrollView and stretching the ScrollView to the size of the window, but then the ImageView is fixed to the top of the screen, and the TableView is scrollable in the bottom half of the screen, whereas everything should scroll together within the window.
I want to create an editable grouped TableView similar to the "Contacts" app on iPhone. For the blue labels on the left I created a label and added them to the TableRow, then added a textfield for the rest of the row. This works, but is it possible to give the label an 'auto' width large enough to fit the text and a bit of padding left and right, and have the textfield on the right to fill the rest of the row (I tried setting the width of the label to 'auto', that doesn't do the trick).
I hope my questions are clear, otherwise leave a comment and I'll make some screenshots describing the problems visually.
Thanks for any help!
0) Nope, there is no "layout" documentation in one nice place.
1) Make the entire display a table. Put the image view into the headerView of a table. That's how I did this:
2) I don't know about textfields, sorry. But as a fallback, you can do labels like above, and then load a separate form in another screen. That may be your simplest/best option.
var baseScrollView = Ti.UI.createScrollView({
top:0,
contentWidth:'auto',
contentHeight:'auto',
showVerticalScrollIndicator:true,
showHorizontalScrollIndicator:false,
backgroundColor:'white',
scrollType : 'vertical'
});
var iv = Ti.UI.createImageView({
borderRadius:10,
top:10,
width:300,
height:300,
image:currentWindow._rowObject["image"]
});
baseScrollView.add(iv);
var data = [];
tableView = Titanium.UI.createTableView({
top:320,
height:400,
scrollable: false,
data:data,
touchEnabled : true,
allowsSelection : false,
font: {
fontFamily:"Trebuchet MS",
fontSize:12
},
style : Titanium.UI.iPhone.TableViewStyle.GROUPED
});
baseScrollView.add(tableView);