BlackBerry Table QML - blackberry-10

How to use the Table Component in BlackBerry 10?
I am having an ImageView and Label.
By default in the Container they are set one on top of another. So instead of the following preview I want to place them horizontally aligned.
Container {
ImageView {
imageSource: "asset:///images/image.png"
}
Label {
preferredHeight: 200
text: "Simple Text"
}
}
And the output of this code is
[Image]
[Text]
and I want to place them as
[Image] [Text]

On your container you need to add an orientation for left to right.
Here would be the example for your code above:
Container {
layout: StackLayout {
orientation: LayoutOrientation.LeftToRight
}
ImageView {
imageSource: "asset:///images/image.png"
}
Label {
preferredHeight: 200
text: "Simple Text"
}
}

Related

Prevent cell content from "jumping" when applying constraint

I have a subclassed UICollectionViewCell and I want it to expand when tapped.
To achieve this, I put the title into a view ("titleStack") and the body into a separate view ("bodyStack"), and then put both of them into a container UIStackView ("mainStack"). I then constrain the contentView of the cell to the leading, trailing, and top edges of mainStack.
When the cell is selected, a constraint is applied that sets the bottom of the contentView's constraint to be the bottom of bodyStack. When it's unselected, I remove that constraint and instead apply one that sets the contentView's bottom constraint equal to titleStack's bottom constraint.
For the most part this works well, but when deselecting, there's this little jump, as you can see in this video:
What I would like is for titleStack to stay pinned to the top while the cell animates the shrinking portion, but it appears to jump to the bottom, giving it a sort of glitchy look. I'm wondering how I can change this.
I've pasted the relevant code below:
private func setUp() {
backgroundColor = .systemGray6
clipsToBounds = true
layer.cornerRadius = cornerRadius
setUpMainStack()
setUpConstraints()
updateAppearance()
}
private func setUpMainStack() {
contentView.constrain(mainStack, using: .edges, padding: 5, except: [.bottom])
mainStack.add([titleStack, bodyStack])
bodyStack.add([countryLabel, foundedLabel, codeLabel, nationalLabel])
}
private func setUpConstraints() {
titleStack.topAnchor.constraint(equalTo: contentView.topAnchor).isActive = true
closedConstraint =
titleStack.bottomAnchor.constraint(equalTo: contentView.bottomAnchor)
closedConstraint?.priority = .defaultLow // use low priority so stack stays pinned to top of cell
openConstraint =
bodyStack.bottomAnchor.constraint(equalTo: contentView.bottomAnchor)
openConstraint?.priority = .defaultLow
}
/// Updates the views to reflect changes in selection
private func updateAppearance() {
UIView.animate(withDuration: 0.3) {
self.closedConstraint?.isActive = !self.isSelected
self.openConstraint?.isActive = self.isSelected
}
}
Thanks so much!
I was able to solve this by simply showing and hiding my "bodyStack" as well as using "layoutIfNeeded." I removed closedConstraint and openConstraint and just gave it a normal bottom constraint.
The relevant code:
func updateAppearance() {
UIView.animate(withDuration: 0.3) {
self.bodyStack.isHidden = !self.isSelected
self.layoutIfNeeded()
}
}

Remove BackgroundView from UITargetedPreview in Swift

I'm trying to remove the background view for my UITargetPreview. I made the background color clear, however, you can still see the frame of the background.
This is what it currently looks like:
I currently have a view that has the text container and the image inside of it and that's what I use as the view for the UITargetedPreview.
Is there a way to only show the image and the text and not the background frame?
There is a tricky method to hide the shadow and to do that you should find a view with _UIPlatterSoftShadowView class name in the view hierarchy and then hide it.
func viewByClassName(view: UIView, className: String) -> UIView? {
let name = NSStringFromClass(type(of: view))
if name == className {
return view
}
else {
for subview in view.subviews {
if let view = viewByClassName(view: subview, className: className) {
return view
}
}
}
return nil
}
override func tableView(_ tableView: UITableView, willDisplayContextMenu configuration: UIContextMenuConfiguration, animator: UIContextMenuInteractionAnimating?) {
DispatchQueue.main.async {
if let window = UIApplication.shared.delegate?.window! {
if let view = self.viewByClassName(view: window, className: "_UIPlatterSoftShadowView") {
view.isHidden = true
}
}
}
}
NOTE: It's not documented internal class and can be changed anytime further but it works now on both ios 13/14.
Have you tried subclassing the UIView as a UIControl?
I had a similar issue but in my case the view for UITargetedPreview was glitchy. However, changing the UIView to a UIControl fixed everything.
try removing shadow of that background view.
You need to study UIBezierPath() to outline the specific area you want to enclose before you present the target view.
After that, you shall assign the specific path to shadow path / visible path
let params = UIPreviewParameters()
params.backgroundColor = .clear
if #available(iOS 14.0, *) {
params.shadowPath = bubblePath
} else {
params.visiblePath = bubblePath
}

How to hide NSCollectionView Scroll indicator

I have an NSCollectionView and I would like to hide the horizontal scroll indicators.
I've tried
collectionView.enclosingScrollView?.verticalScroller?.isHidden = true
But it is not working.
Thank you in advance.
hidden didn't work for me too.
The only way I found to hack this, is by changing inset:
(scrollViewCollectionView is of type NSScrollView, this example is while creating NSCollectionView programmatically)
scrollViewCollectionView.documentView?.enclosingScrollView?.scrollerInsets = NSEdgeInsets.init(top: 0, left: 0, bottom: 100, right: 0)
Please note: My NSCollectionView is horizontal, and less then 100 height, this is why this hack resolved in a hidden indicator.
Override hasHorizontalScroller or horizontalScroller to false and nil will cause NSScroller not to be displayed, and NSScrollView will not respond to scroll events.
This means that you can't scroll through NSScrollView's many scrolling methods.
When hasHorizontalScroller = true, horizontalScroller != nil will cause a drawing error.
class MyScrollView : NSScrollView {
// !!! Don't use this !!!
override var hasHorizontalScroller: Bool {
get {
// return false will cause NSScroller not to be displayed
// and NSScrollView will not respond to scroll events,
// this means that you can't scroll through NSScrollView's many scrolling methods.
false
}
set {
super.hasHorizontalScroller = newValue
}
}
// !!! Don't use this !!!
override var horizontalScroller: NSScroller? {
get {
// return nil will cause NSScroller not to be displayed,
// but it still occupies the drawing area of the parent view.
nil
}
set {
super.horizontalScroller = newValue
}
}
}
This is the way to hide NSScroller and respond to scroll events correctly. Only useful in versions above 10.7:
class HiddenScroller: NSScroller {
// #available(macOS 10.7, *)
// let NSScroller tell NSScrollView that its own width is 0, so that it will not really occupy the drawing area.
override class func scrollerWidth(for controlSize: ControlSize, scrollerStyle: Style) -> CGFloat {
0
}
}
Create an outlet for the ScrollView which contains the CollectionView as seen here. I've named mine #IBOutlet weak var collectionViewScrollView: NSScrollView!
in viewDidAppear() function add:
collectionViewScrollView.scrollerStyle = .legacy
collectionViewScrollView.verticalScroller?.isHidden = true - for vertical scroll
collectionViewScrollView.horizontalScroller?.isHidden = true - for horizontal scroll
For some reason, in my case it only works if I set the collectionViewScrollView.scrollerStyle to .legacy. Not sure why, but it works.
Setting "Show Vertical Scroller" or "Show Horizontal Scroller" in storyboard doesn't remove the scrollers without setting constrains (height and width) of Bordered Scroll View of Collection View. After I did that and unchecked "Show Vertical Scroller" and "Show Horizontal Scroller" in Attributes Panel in storyboard they disappeared.
I got same problem and just solve it. You can write your own custom NSScrollView and override 2 stored property: hasHorizontalScroller, horizontalScroller, and 1 function scrollWheel(with:). Here's my code:
class MyScrollView: NSScrollView {
override var hasHorizontalScroller: Bool {
get {
return false
}
set {
super.hasHorizontalScroller = newValue
}
}
override var horizontalScroller: NSScroller? {
get {
return nil
}
set {
super.horizontalScroller = newValue
}
}
//comment it or use super for scrroling
override func scrollWheel(with event: NSEvent) {}
}
And don't forget to set Border Scroll View class to MyScrollView in .xib or storyboard.
Enjoy it!
You can also achieve that via storyboard
I also meet the same problem. MCMatan is right. Please adjust the position of scroller to some place invisible.
scrollView.scrollerInsets = NSEdgeInsets.init(top: 0, left: 0, bottom: -10, right: 0)
for Swift 4 & 5 in UIKit:
for Horizontal:
collectionView.showsHorizontalScrollIndicator = false
For Vertical:
collectionView.showsVerticalScrollIndicator = false
In my case, the horizontal and vertical scroller of the collection scroll view are only hidden if do exactly as follow:
1. In Interface Builder.
1.a. Select Scroll View —> Attributes Inspector:
+ Uncheck Show Horizontal Scroller.
+ Uncheck Show Vertical Scroller.
+ Uncheck Automactically Hide Scroller.
1.b. Select Size Inspector:
+ Uncheck Automatically Adjust.
1.c. Select Clip View —> Size Inspector:
+ Uncheck Automatically Adjust.
2. In code do exactly as follow:
[self.scrollView setBackgroundColor:[NSColor clearColor]];
[self.scrollView setBorderType:NSNoBorder];
[self.scrollView setHasVerticalScroller:NO];
[self.scrollView setHasHorizontalScroller:NO];
[self.scrollView setAutomaticallyAdjustsContentInsets:NO];
[self.scrollView setContentInsets:NSEdgeInsetsMake(0.0, 0.0, -NSHeight([self.scrollView horizontalScroller].frame), -NSWidth([self.scrollView verticalScroller].frame))];
[self.scrollView setScrollerInsets:NSEdgeInsetsMake(0.0, 0.0, -NSHeight([self.scrollView horizontalScroller].frame), -NSWidth([self.scrollView verticalScroller].frame))];
[self.scrollView setScrollEnable:NO];
NSClipView *clipView = (NSClipView *)[self.scrollView documentView];
if ([clipView isKindOfClass:[NSClipView class]])
{
[clipView setAutomaticallyAdjustsContentInsets:NO];
[clipView setContentInsets:NSEdgeInsetsZero];
}
Then the NSCollectionView will fit to the Clip View as same width and height without the horizontal and vertical scrollers.
If someone still needs it, this one trick should work
collectionView.enclosingScrollView?.horizontalScroller?.alphaValue = 0.0

Dragging NSSplitView divider does not resize views

I'm working with Cocoa and I create my views in code (no IB) and I'm hitting an issue with NSSplitView.
I have a NSSplitView that I configure in the following way in my view controller, in Swift:
override func viewDidLoad() {
super.viewDidLoad()
let splitView = NSSplitView()
splitView.isVertical = true
splitView.addArrangedSubview(self.createLeftPanel())
splitView.addArrangedSubview(self.createRightPanel())
splitView.adjustSubviews()
self.view.addSubview(splitView)
...
}
The resulting view shows the two subviews and the divider for the NSSplitView, and one view is wider than the other. When I drag the diver to change the width, as soon as I release the mouse, the divider goes back to its original position, as if pulled back by a "spring".
I can't resize the two subviews; the right one always keeps a fixed size. However, nowhere in the code I fix the width of that subview, or any of its content, to a constant.
What I would like to achieve instead is that the right view size is not fixed, and that if I drag the divider at halfway through, the subviews will resize accordingly and end up with the same width.
This is a screen recording of the problem:
Edit: here is how I set the constraints. I'm using Carthography, because otherwise setting constraints in code is extremely verbose beyond the most simple cases.
private func createLeftPanel() -> NSView {
let view = NSView()
let table = self.createTable()
view.addSubview(table)
constrain(view, table) { view, table in // Cartography magic.
table.edges == view.edges // this just constraints table.trailing to
// view.trailing, table.top to view.top, etc.
}
return view
}
private func createRightPanel() -> NSView {
let view = NSView()
let label = NSTextField(labelWithString: "Name of item")
view.addSubview(label)
constrain(view, label) { view, label in
label.edges == view.edges
}
return view
}

When I add a view using AutoLayout to a UIScrollView as a subview, everything looks wrong

My application contains a form that is presented to the user as a subview of a UIScrollView. The form view is controlled by a FormViewController. The UIScrollView takes up the whole screen. The form view has a height of 800 points and a width equal to the screen width. I want to place the form 70% towards the bottom of the screen, to let the user see an image below the scroll view. The form view contains labels, text fields, and other views all constrained using AutoLayout. The background of the form is white.
When I add the form view as a subview however, the labels show up above the main form area, in the area where the background is not white. This is what I'm using to add the form view to the UIScrollView in Swift:
func setUpForm() {
self.formContentHeight = 0
self.formContentHeight += CGFloat(Int(UIScreen.mainScreen().bounds.size.height * 0.7))
var form:FormViewController = self.storyboard?.instantiateViewControllerWithIdentifier("formviewcontroller") as! FormViewController
form.view.frame = CGRectMake(0, self.formContentHeight, self.formContentWidth, 800)
self.formScrollView.addSubview(form.view)
self.formContentHeight += 800
self.formScrollView.contentSize = CGSizeMake(self.formContentWidth, self.formContentHeight)
}
This is the result:
When I simply present the FormViewController using presentViewController(), everything is fine:
func setUpForm() {
presentViewController(form, animated: true, completion: nil)
}
Result:
Here's the FormViewController in the Storyboard:
What could be happening here?