UIDatePicker, UIActionSheet, and Data handling - xcode4

So I understand how to pull the date from a date picker just fine. But I can't seem to be able to pull it from a date picker on a UIActionSheet. Our current set up is a form for entering data with a few pickers, all using the didSelectRow method for the data source, all of them using the same view for said data source.
Now this doesn't work for a UIDatePicker in the same way, it seems. Here is what I have so far for my date picker, it's similar to my other pickers, including the methods to handle changing of values.
-(IBAction)ageBox{
pickerAction=[[UIActionSheet alloc]initWithTitle:nil delegate:nil cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:nil];
[pickerAction setActionSheetStyle:UIActionSheetStyleBlackTranslucent];
CGRect pickerFrame = CGRectMake(0, 40, 0, 0);
UIDatePicker *datePicker =[[UIDatePicker alloc]initWithFrame:pickerFrame];
[pickerAction addSubview:datePicker];
UISegmentedControl *closeButton=[[UISegmentedControl alloc]initWithItems:[NSArray arrayWithObject:#"OK"] ];
closeButton.momentary = YES;
closeButton.frame=CGRectMake(260, 7.0f, 50.0f, 30.0f);
closeButton.segmentedControlStyle =UISegmentedControlStyleBar;
closeButton.tintColor = [UIColor blackColor];
date = datePicker.date;
[closeButton addTarget:self action:#selector(closePicker) forControlEvents:UIControlEventValueChanged];
[pickerAction addSubview:closeButton];
whatToChange = 5;
[pickerAction showInView:self.view];
[pickerAction setBounds:CGRectMake(0, 0, 320, 464)];
}
Any help pulling the date from the date picker while it's on the action sheet, or when I click ok, pulling it from it before it's destroyed?

I'm making the assumption that pickerAction is an ivar of self, based on the first line of code in the method. I can think of a couple of ways, I'm sure there are more.
1) Make datePicker an ivar as well. That way you have a reference to it for your 'ok' method.
2) Obtain the reference from the pickerAction itself. Since you have added the datePicker as a subview, you can find it like so:
// Somewhere in your "ok" method
for (UIView *view in pickerAction.subviews) {
if ([view isKindOfClass:[UIDatePicker class]]){
UIDatePicker *picker = (UIDatePicker *)view;
NSDate *pickedDate = picker.date;
}
}

Related

Remove date from Time in Google App Script

I am new to script and found a code that I have been tweaking for my needs but I keep running into a problem since I separated the date and time. My date field display and selected value match but the time fields keep defaulting to MM/DD/YY HH:MM A/P when selected. en I click on it (it displays correctly when not selected). I need to have the field only display the time and nothing else. so it will stop causing issues to my formulas on other sheets. I know my problem lies in the last part but so far what I have tried has failed.
//DEFINE ALL ACTIVE SHEETS
var ss = SpreadsheetApp.getActiveSpreadsheet();
//DEFINE MAIN SHEET
var mainSheet = ss.getSheetByName("MAIN");
//LAST ROW ON MAIN SHEET
var lastRow = mainSheet.getLastRow();
for (var j = 5; j <= lastRow; j++)
{
// CHECK CLOCK IN
if(mainSheet.getRange('b1:b1').getValue() == mainSheet.getRange(j, 1).getValue() && mainSheet.getRange(j,3).getValue() == '')
{
Browser.msgBox('Need to Clock Out before Clocking IN');
return;
}
}
// ADD CLOCK IN RECORD
mainSheet.getRange(lastRow + 1, 1).setValue(mainSheet.getRange('b1:b1').getValue()).setFontSize(12);
mainSheet.getRange(lastRow + 1, 2).setValue(new Date(new Date().setHours(0, 0, 0, 0))).setNumberFormat('MM/DD/YY').setHorizontalAlignment("center").setFontSize(12);
mainSheet.getRange(lastRow + 1, 3).setValue(new Date()).setNumberFormat("hh:mm A/P").setHorizontalAlignment("center").setFontSize(12);//````
You get a whole bunch of formatting options if you look for Utilities.formatDate
var date = Utilities.formatDate(new Date(), "Europe/Berlin", "dd.MM.yyyy")
var time = Utilities.formatDate(new Date(), "Europe/Berlin", "HH:mm")
Change "Europe/Berlin" to your location to get the current time. Now use the variables wherever you need them. Simple as that.
Pro tip: Try to use variables (just like shown above) for readability instead of fitting everything in one line.

X++ assign Enum Value to a table column

I am trying to pull the Enum chosen from a dialog and assign the label to a table's column.
For example: Dialog opens and allows you to choose from:
Surface
OutOfSpec
Other
These are 0,1,2 respectively.
The user chooses OutOfSpec (the label for this is Out Of Spec), I want to put this enum's Name, or the label, into a table. The column I'm inserting into is set to be a str.
Here's the code I've tried, without success:
SysDictEnum dictEnum = new SysDictEnum(enumNum(SDILF_ScrapReasons));
reason = dialog.addField(enumStr(SDILF_ScrapReasons),"Scrap Reason");
dialog.run();
if (!dialog.closedOk())
{
info(reason.value());
return;
}
ttsBegin;
// For now, this will strip off the order ID from the summary fields.
// No longer removing the Order ID
batchAttr = PdsBatchAttributes::find(itemId, invDim.inventBatchId, "OrderId");
orders = SDILF_BreakdownOrders::find(batchAttr.PdsBatchAttribValue, true);
if (orders)
{
orders.BoxProduced -= 1;
orders.update();
}
// Adding a batch attribute that will include the reason for scrapping
select forUpdate batchAttr;
batchAttr.PdsBatchAttribId = "ScrapReason";
//batchAttr.PdsBatchAttribValue = any2str(dictEnum.index2Value(reason.value()));
batchAttr.PdsBatchAttribValue = enum2str(reason.value());
batchAttr.InventBatchId = invDim.inventBatchId;
batchAttr.ItemId = itemId;
batchAttr.insert();
Obviously this is not the whole code, but it should be enough to give the issue that I'm trying to solve.
I'm sure there is a way to get the int value and use that to assign the label, I've just not been able to figure it out yet.
EDIT
To add some more information about what I am trying to accomplish. We make our finished goods, sometimes they are out of spec or damaged when this happens we then have to scrap that finished good. When we do this we want to keep track of why it is being scrapped, but we don't want just a bunch of random reasons. I used an enum to limit the reasons. When the operator clicks the button to scrap something they will get a dialog screen pop-up that allows them to select a reason for scrapping. The code will then, eventually, put that assigned reason on that finished items batch attributes so that we can track it later in a report and have a list of all the finished goods that were scrapped and why they were scrapped.
I'm not entirely sure of your question, but I think you're just missing one of the index2[...] calls or you're not getting the return value from your dialog correctly. Just create the below as a new job, run it, make a selection of Open Order and click ok.
I don't know the difference between index2Label and index2Name.
static void Job67(Args _args)
{
Dialog dialog = new dialog();
SysDictEnum dictEnum = new SysDictEnum(enumNum(SalesStatus));
DialogField reason;
SalesStatus salesStatusUserSelection;
str label, name, symbol;
int value;
reason = dialog.addField(enumStr(SalesStatus), "SalesStatus");
dialog.run();
if (dialog.closedOk())
{
salesStatusUserSelection = reason.value();
// Label
label = dictEnum.index2Label(salesStatusUserSelection);
// Name
name = dictEnum.index2Name(salesStatusUserSelection);
// Symbol
symbol = dictEnum.index2Symbol(salesStatusUserSelection);
// Value
value = dictEnum.index2Value(salesStatusUserSelection);
info(strFmt("Label: %1; Name: %2; Symbol: %3; Value: %4", label, name, symbol, value));
}
}

momentjs - strange behave with startOf and endOf

I'm trying to get the start and the end a a specific day.
Here's the code:
var newDay, newDayEnd, newDayStart;
if (newDay === '') {
newDay = moment();
}
newDay.subtract('day', 1);
newDayStart = newDay.startOf('day');
newDayEnd = newDay.endOf('day');
I'm trying to debug it, and I noticed that when if goes trough the values are correct, but as soon as it reaches newDay.endOf('day') it sets all the variable to the end of the specified day (23.59.59)
I'm using the above function on button click. Every time I click a button, it goes back one day (newDay.subtract('day', 1)) and I need to be able to get start and end of the new day (newDay variable)
Any help?
What am I doing wrong here? I don't understand.
Thanks
Moment objects are mutable, so you have to clone() them before modifying them.
As you can read from the endOf docs:
Mutates the original moment by setting it to the end of a unit of time.
Working example:
var newDay, newDayEnd, newDayStart;
newDay = moment().subtract(1, 'day');
newDayStart = newDay.clone().startOf('day');
newDayEnd = newDay.clone().endOf('day');
console.log(newDayStart.format(), newDayEnd.format());
<script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.13.0/moment.min.js"></script>

View-based NSOutlineView without NIB?

NSOutlineView is a subclass of NSTableView. And currently, NSTableView supports two implementations.
Cell-based.
View-based.
To make OSX 10.8 Finder style side bar (with automatic gray Icon styling), need to use view-based table view with source-list highlight style.
With NIBs, this is typical job. Nothing hard. (see SidebarDemo) But I want to avoid any NIBs or Interface Builder. I want make the side bar purely programmatically.
In this case, I have big problem. AFAIK, there's no way to supply prototype view for specific cell. When I open .xib file, I see <tableColumn> is containing <prototypeCellViews>. And this specifies what view will be used for the column. I can't find how to set this programmatically using public API.
As a workaround, I tried to make cell manually using -[NSTableView makeViewWithIdentifier:owner:] and -[NSTableView viewAtColumn:row:makeIfNecessary:], but none of them returns view instance. I created a NSTableCellView, but it doesn't have image-view and text-field instances. And I also tried to set them, but the fields are marked as assign so the instances deallocated immediately. I tried to keep it by forcing retaining them, but it doesn't work. NSTableView doesn't manage them, so I am sure that table view don't like my implementation.
I believe there's a property to set this prototype-view for a column. But I can't find them. Where can I find the property and make system-default NSOutlineView with source-list style programmatically?
If you follow the example in SidebarDemo, they use a subclass of NSTableCellView for the detail rows. In order to emulate the InterfaceBuilder mojo, you can hook everything together in the constructor. The rest is the same as the demo (see outlineView:viewForTableColumn:item:).
#interface SCTableCellView : NSTableCellView
#end
#implementation SCTableCellView
- (id)initWithFrame:(NSRect)frameRect {
self = [super initWithFrame:frameRect];
[self setAutoresizingMask:NSViewWidthSizable];
NSImageView* iv = [[NSImageView alloc] initWithFrame:NSMakeRect(0, 6, 16, 16)];
NSTextField* tf = [[NSTextField alloc] initWithFrame:NSMakeRect(21, 6, 200, 14)];
NSButton* btn = [[NSButton alloc] initWithFrame:NSMakeRect(0, 3, 16, 16)];
[iv setImageScaling:NSImageScaleProportionallyUpOrDown];
[iv setImageAlignment:NSImageAlignCenter];
[tf setBordered:NO];
[tf setDrawsBackground:NO];
[[btn cell] setControlSize:NSSmallControlSize];
[[btn cell] setBezelStyle:NSInlineBezelStyle];
[[btn cell] setButtonType:NSMomentaryPushInButton];
[[btn cell] setFont:[NSFont boldSystemFontOfSize:10]];
[[btn cell] setAlignment:NSCenterTextAlignment];
[self setImageView:iv];
[self setTextField:tf];
[self addSubview:iv];
[self addSubview:tf];
[self addSubview:btn];
return self;
}
- (NSButton*)button {
return [[self subviews] objectAtIndex:2];
}
- (void)viewWillDraw {
[super viewWillDraw];
NSButton* btn = [self button];
...
Here's #jeberle's code re-written in Swift 4 (five years later!):
class ProgrammaticTableCellView: NSTableCellView {
override init(frame frameRect: NSRect) {
super.init(frame: frameRect)
self.autoresizingMask = .width
let iv: NSImageView = NSImageView(frame: NSMakeRect(0, 6, 16, 16))
let tf: NSTextField = NSTextField(frame: NSMakeRect(21, 6, 200, 14))
let btn: NSButton = NSButton(frame: NSMakeRect(0, 3, 16, 16))
iv.imageScaling = .scaleProportionallyUpOrDown
iv.imageAlignment = .alignCenter
tf.isBordered = false
tf.drawsBackground = false
btn.cell?.controlSize = .small
// btn.bezelStyle = .inline // Deprecated?
btn.cell?.isBezeled = true // Closest property I can find.
// btn.cell?.setButtonType(.momentaryPushIn) // Deprecated?
btn.setButtonType(.momentaryPushIn)
btn.cell?.font = NSFont.boldSystemFont(ofSize: 10)
btn.cell?.alignment = .center
self.imageView = iv
self.textField = tf
self.addSubview(iv)
self.addSubview(tf)
self.addSubview(btn)
}
required init?(coder decoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
var button: NSButton {
get {
return self.subviews[2] as! NSButton
}
}
}
Edit: I found a link (that will inevitably rot away – it was last revised in 2011) to Apple's SidebarDemo that #jeberle based his code on.
In addition to #jeberle 's answer, I need to note something more.
The key to keep the text-field and image-view is adding them as subviews of the NSTableCellView.
Set NSTableView.rowSizeStyle to a proper value (non-Custom which is default value) to make the table-view layout them automatically. Otherwise, you have to layout them completely yourself.
Do not touch frame and autoresizing stuffs if you want to use predefined NSTableViewRowSizeStyle value. Otherwise, the layout might be broken.
You can adjust row-height by providing private func outlineView(outlineView: NSOutlineView, heightOfRowByItem item: AnyObject) -> CGFloat delegate method. Setting NSTableView.rowHeight is not a good idea because it needs NSTableView.rowSizeStyle set to Custom which will turn off cell text/image layout management provided by default.
You can reuse row/cell views by settings NSView.identifier property. (example)

Firebase FQuery how do you detect when at the end of a list of nodes

How do I detect when I have finished processing all found nodes when doing a query? In the following example, I do some processing on each encountered node. When I reach the "end" of the list I would like to be able to detect this so I know it's finished.
FQuery* messageListQuery = [m_firebaseRef queryLimitedToNumberOfChildren:100];
[messageListQuery observeEventType:FEventTypeChildAdded andPreviousSiblingNameWithBlock:^(FDataSnapshot *snapshot, NSString *prevNodeName) {
// 1. Do interesting stuff with the snapshot data
// 2. I want to detect when I'm at the end of the list so I know when I'm done processing the list.
}];
Here is the example use case. I would like to load the latest 100 messages in the background. Once the messages have been loaded, I would like to update the UI. However, I'm not sure how I know all the messages have been loaded given there might be less then 100 messages in the list.
I figured out how to read all the messages up front by using the observeSingleEventOfType and then iterating over the children.
[m_firebaseRef observeSingleEventOfType:FEventTypeValue withBlock:^(FDataSnapshot *snapshot) {
NSLog( #"Name %# with %d children.", snapshot.name, snapshot.childrenCount );
for( FDataSnapshot *child in snapshot.children )
{
NSDictionary *msgData = child.value;
NSString *message = msgData[kFirebaseLiveChatFieldMessage];
NSString *gamerTag = msgData[kFirebaseLiveChatFieldGamerTag];
NSString *gameCenterId = msgData[kFirebaseLiveChatFieldGameCenterId];
NSLog( #"Preload = %# (%#): %#", gamerTag, gameCenterId, message );
}
}];

Resources