UIStackView not calling draw of custom UIView - uikit

I have a UIView with a custom draw(_ rect: CGRect) method, which works.
However, when I place it inside a UIStackView, its draw method is not called. UILabel or UIImage inside the same stack view display normally.
In Interface Builder, it is drawn even inside the stack view, but when running on the device, it's not.

draw(_ rect: CGRect) doesn't call in addArrangedSubview of stack.
Instead you can put your code into layoutSubviews.

Solved it by adding a wrapper view first and after adding it to the UIStackView, i added my Custom-Drawing view into the wrapper view.
(This is written in C# but I'm pretty sure it'll help anyway)
UIView wrapperView = new UIView(f);
CanvasStackView.AddArrangedSubview(wrapperView);
CGRect f = new CGRect(CGPoint.Empty,new CGSize(CanvasStackView.Frame.Size.Width, height));
MyCustomView b = new MyCustomView(f);
wrapperView.AddSubview(b);

Related

drawRect not being called for NSTableView cell view

I have a view-based NSTableView with my custom view and the normal NSTextField in it. The custom view's background colour should change when a user clicks and it doesn't work because drawRect is not being called. I don't understand why really. Here's the delegate method and custom view code.
MyController
- (void)didAddLabel:(id)sender {
CustomLabel *label = (CustomLabel *)sender;
NSTableRowView *aaa = [_tableView rowViewAtRow:_tableView.selectedRow makeIfNecessary:NO];
MyCustomView *hello = [((NSTableCellView*)[aaa viewAtColumn:0]).subviews objectAtIndex:0];
[hello setBackgroundColor:[label nscolor]];
NSLog(#"Background colour is %#", [hello backgroundColor]);
[hello setNeedsDisplay:YES];
}
My view
class MyCustomView: NSView {
var backgroundColor :NSColor = NSColor.purpleColor()
override func drawRect(dirtyRect: NSRect) {
NSLog("In here")
backgroundColor.setFill()
NSRectFill(dirtyRect)
}
}
Observations: 1) the drawRect is only called upon init of the app. 2) The NSLog row contains the new/selected colour however the background does not change from purple.
Question: why isn't drawRect: called after setNeedsDisplay:?
drawRect: is only called if you don't have layer backing turned on. Are any of the parent views / this view have wantsLayer = YES or have a CALayer assigned to it? In that case, you'll have to use updateLayer: since all children of a layer-backed view are automatically layer-backed.

Get real height size of a cell from UITableViewCell

On a custom UITableViewCell, what are the best location to have the real(custom) height of a cell.
I've try
override func awakeFromNib() {
btnIsFav.center.y = self.center.y
But look like awakeFromNib are called to soon to have the real info of the custom height.
Thanks :)
You should use layoutSubviews. that's when the cell begins to initialize its subviews

UiScrollview with nested image looks weird

I have a UIScrollView inside a UIViewController (subclassed by ImageViewController). The ViewController itself is part of a NavigationController's stack. Now, apart from having a navigation bar, I want the ScrollView to take all of the available room on the screen. The UIImageView inside the scrollview should then fill the available room of the scroll view. You can see the current state at the bottom of this posting.
class ImageViewController: UIViewController, UIScrollViewDelegate {
#IBOutlet weak var scrollView: UIScrollView!
var imageView: UIImageView?
var image: UIImage?
override func viewDidLoad() {
super.viewDidLoad()
scrollView.delegate = self
if let image = image {
imageView = UIImageView(image: image)
if let imageView = imageView {
imageView.frame = CGRect(origin: CGPoint(x: 0, y: 0), size: image.size)
scrollView.addSubview(imageView)
scrollView.contentSize = image.size
let scaleHeight = scrollView.frame.size.height / scrollView.contentSize.height
let scaleWidth = scrollView.frame.size.width / scrollView.contentSize.width
let minimumScale:CGFloat = min(scaleHeight, scaleWidth)
let maximumScale:CGFloat = max(scaleHeight, scaleWidth)
scrollView.minimumZoomScale = minimumScale
scrollView.maximumZoomScale = maximumScale
scrollView.zoomScale = maximumScale
}
}
}
func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView? {
return imageView
}
}
The code leaves me with unnecessary borders (left, right, top). How do I get rid of them?
EDIT: With #Bxtr's suggestion and another stackoverflow thread I was able to remove the borders left and right to the scroll view. After some more digging I found out that by deactivating Adjust Scroll View Insets, the image inside the scroll view can be correctly vertically positioned. Still, I do not get the reason for the vertical misplacement in the first place...
Have you checked the margin/padding values, because it kinda looks so (same size on left and right border). If it is not the case, could you please also post your xml file of the activity so we can have every part of the puzzle to help you ?
scrollView.contentSize = image.size;
you have to tweek this line. You are explicitly setting scroll view content size to the image size. You have to set content size to fit the Width of Screen.
You can use a UIView in UIScrollView, and that UIView contains UIImage.
You need to set constraints properly.
After some more digging I found out that by deactivating Adjust Scroll
View Insets, the image inside the scroll view can be correctly
vertically positioned. Still, I do not get the reason for the vertical
misplacement in the first place...
The reason is that the view controller's automaticallyAdjustsScrollViewInsets property is by default YES, the following is from apple documentation:
automaticallyAdjustsScrollViewInsets
A Boolean value that indicates
whether the view controller should automatically adjust its scroll
view insets.
Default value is YES, which allows the view controller to adjust its
scroll view insets in response to the screen areas consumed by the
status bar, navigation bar, and toolbar or tab bar. Set to NO if you
want to manage scroll view inset adjustments yourself, such as when
there is more than one scroll view in the view hierarchy.
Besides setting automaticallyAdjustsScrollViewInsets = No, you can pin the scrollView to the topLayoutGuide (instead of to the top of the viewController's view) when using autoLayout.

cocoa - Edit/Design NSView visually

How can I visually design a NSView in Xcode? I'm trying to build a statusBar app with a statusMenu only
As you can see above, the object appear but I can't edit it visually, then it go like this as a result:
I attempted to use a XIB file (only have a NSView, no ViewController), but I can't put the NSView in the XIB into the AppDelegate. I tried another ways and managed to use the XIB file, but then I can't use the Storyboard.
Do you have any idea for this situation?
UPDATE
Thank Max for answer my question. I actually tried that before but failed. I tried it again after your comment and there's still no luck. Here is how I did
I created a ViewController then I change its view to the MenuCustomView (NSView)
This is the code in AppDelegate
let statusBar = NSStatusBar.systemStatusBar().statusItemWithLength(-1)
var menuCustomView = NSView()
func applicationDidFinishLaunching(aNotification: NSNotification) {
// Insert code here to initialize your application
let statusIcon = NSImage(named: "statusIcon")
let statusMenu = NSMenu()
statusBar.image = statusIcon
statusBar.menu = statusMenu
let menuItem = NSMenuItem()
menuItem.title = "title"
var vc = ViewController()
menuCustomView = vc.view
menuItem.view = menuCustomView
statusMenu.addItem(menuItem)
}
Files I have in the project
Even though you don't need the view controller, you can use them to design the views. Create one in the storyboard, edit the view the way you want.
Then you can use the view by creating a viewController out of the storyboard and using its view property to attach the view to the NSStatusBarItem
My words in code:
let storyboard = NSStoryboard(name: "Main", bundle: nil)
let viewController = storyboard?.instantiateControllerWithIdentifier("MyViewController") as! NSViewController
let view = viewController.view
I assume you want to add functioning code to the view. To, for example respond to the button click, you have to subclass the NSViewController and then implement the code you would have added to the AppDelegate.
If you need any more explanation, feel free to write me :)

Xcode: How to fix the toolbar for a tableView?

I have a tableView and want to add a toolbar at the bottom with a sync button and the latest sync date (like on the Mail-app on the iPhone). But the Scrollbar should be fixed, so that it doesn't move when I scroll trough the table view.
Right now, I'm just adding the searchBar programmatically by:
self.tableView.tableFooterView = self.toolbar;
Another problem linked here is the fact, that I'm using the MasterDetailsView Controller template of Xcode. But I can't just drag a toolbar into my MasterView (containing the tableview). My first guess is that its just fixed because of the template I used but I'm not quite sure about it.
Thanks in advance!!
Instead of using a UITableViewController try using a plain UIViewController which conforms to UITableViewDelegate and UITableViewDataSource. Add a UITableView as a subview to the view controller's main view and link its delegate and datasource to the view controller.
Now, you can add any other UIViews to the main view which will appear fixed on top of the UITableView.
In your Story board for that ViewController, drag Bar Button Item to the Bottom after the tableView and in viewDidLoad method.. do the following..
self.navigationController.toolbarHidden = NO;
I think I found a really good solution to this.
In the storyboard view, drop the toolbar out of the Tableview. In the story board view this will leave it 'floating' above the view and the tool bar will no longer appear in your compiled code.
Too fix this, add the following to your view controller code
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let v = UIView()
let toolBarView : UIView = UIView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 44))
mainToolBar.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 44)
toolBarView.addSubview(mainToolBar)
v.addSubview(toolBarView)
return v
}

Resources