Macos 使用NSPredicateEditor筛选一天的最佳方法

Macos 使用NSPredicateEditor筛选一天的最佳方法,macos,nspredicateeditor,Macos,Nspredicateeditor,是否有人使用NSPredicateEditor找到了一种按天过滤数据(CoreData)的解决方案?这样做的目的是让它对用户来说最方便。标准解决方案是为日期定义两个标准: 一个用于>=一天的开始 另一个用于的行模板可以转换谓词中的谓词(使用subpredicates:),无需其他重写。在IB中,正确的表达是日期 override func predicate(withSubpredicates subpredicates: [NSPredicate]?) -> NSPredicate {

是否有人使用NSPredicateEditor找到了一种按天过滤数据(CoreData)的解决方案?这样做的目的是让它对用户来说最方便。标准解决方案是为日期定义两个标准:

  • 一个用于>=一天的开始

  • 另一个用于的行模板可以转换
    谓词中的谓词(使用subpredicates:)
    ,无需其他重写。在IB中,正确的表达是日期

    override func predicate(withSubpredicates subpredicates: [NSPredicate]?) -> NSPredicate {
        // call super to get the predicate, for example aDate == '3.5.20210 14:03:53'
        let predicate = super.predicate(withSubpredicates: subpredicates)
        // convert the predicate to aDate >= '3.5.2021 00:00:00' AND aDate < '4.5.2021 00:00:00'
        var newPredicate = predicate
        if let comparisonPredicate = predicate as? NSComparisonPredicate,
            let predicateDate = comparisonPredicate.rightExpression.constantValue as? Date {
            let keyPath = comparisonPredicate.leftExpression.keyPath
            var components = Calendar.current.dateComponents([.year, .month, .day], from: predicateDate)
            components.hour = 0
            components.minute = 0
            components.second = 0
            components.calendar = NSCalendar.current
            switch comparisonPredicate.predicateOperatorType {
                case .lessThan:
                    // aDate < '3.5.2021 00:00:00'
                    let date = components.date! as NSDate
                    newPredicate = NSPredicate(format: "%K < %@", keyPath,date)
                case .lessThanOrEqualTo:
                    // aDate < '4.5.2021 00:00:00'
                    components.day = components.day! + 1
                    let date = components.date! as NSDate
                    newPredicate = NSPredicate(format: "%K < %@", keyPath,date)
                case .greaterThan:
                    // aDate >= '4.5.2021 00:00:00'
                    components.day = components.day! + 1
                    let date = components.date! as NSDate
                    newPredicate = NSPredicate(format: "%K >= %@", keyPath,date)
                case .greaterThanOrEqualTo:
                    // aDate >= '3.5.2021 00:00:00'
                    let date = components.date! as NSDate
                    newPredicate = NSPredicate(format: "%K >= %@", keyPath,date)
                case .equalTo:
                    // aDate >= '3.5.2021 00:00:00' AND aDate < '4.5.2021 00:00:00'
                    let startDate = components.date! as NSDate
                    components.day = components.day! + 1
                    let endDate = components.date! as NSDate
                    newPredicate = NSPredicate(format: "%K >= %@ AND %K < %@", keyPath, startDate, keyPath, endDate)
                case .notEqualTo:
                    // NOT (aDate >= '3.5.2021 00:00:00' AND aDate < '4.5.2021 00:00:00')
                    let startDate = components.date! as NSDate
                    components.day = components.day! + 1
                    let endDate = components.date! as NSDate
                    newPredicate = NSPredicate(format: "NOT (%K >= %@ AND %K < %@)", keyPath, startDate, keyPath, endDate)
                default:
                    newPredicate = predicate
            }
        }
        return newPredicate
    }
    
    override func谓词(带有子谓词subpredicates:[NSPredicate]?)->NSPredicate{
    //调用super获取谓词,例如aDate==“3.5.20210 14:03:53”
    let predicate=super.predicate(带子谓词:子谓词)
    //将谓词转换为aDate>='3.5.2021 00:00:00'和aDate<'4.5.2021 00:00:00'
    var newPredicate=谓词
    如果让comparisonPredicate=谓词为?NSComparisonPredicate,
    让predicateDate=comparisonPredicate.rightExpression.constantValue作为?日期{
    让keyPath=comparisonPredicate.leftExpression.keyPath
    var components=Calendar.current.dateComponents([.year、.month、.day],from:predictedate)
    组件。小时=0
    组件。分钟=0
    组件。秒=0
    components.calendar=NSCalendar.current
    开关比较Predicate.predicateOperatorType{
    案例.莱斯特尚:
    //aDate<'2021年5月3日00:00:00'
    让date=components.date!作为NSDate
    newPredicate=NSPredicate(格式:“%K<%@”,键路径,日期)
    案例:lessThanOrEqualTo:
    //aDate<'2021年5月4日00:00:00'
    components.day=components.day!+1
    让date=components.date!作为NSDate
    newPredicate=NSPredicate(格式:“%K<%@”,键路径,日期)
    案例。大于:
    //日期>='4.5.2021 00:00:00'
    components.day=components.day!+1
    让date=components.date!作为NSDate
    newPredicate=NSPredicate(格式:'%K>=%@',键路径,日期)
    案例。大于或等于:
    //日期>='2021年5月3日00:00:00'
    让date=components.date!作为NSDate
    newPredicate=NSPredicate(格式:'%K>=%@',键路径,日期)
    案例.平等:
    //aDate>='2021年5月3日00:00:00'和aDate<'2021年5月4日00:00:00'
    将startDate=components.date!设为NSDate
    components.day=components.day!+1
    让endDate=components.date!作为NSDate
    newPredicate=NSPredicate(格式:“%K>=%@和%K<%@”,键路径,起始日期,键路径,结束日期)
    案例。注意事项:
    //不是(aDate>='2021年5月3日00:00:00'和aDate<'2021年5月4日00:00:00')
    将startDate=components.date!设为NSDate
    components.day=components.day!+1
    让endDate=components.date!作为NSDate
    newPredicate=NSPredicate(格式:“非(%K>=%@和%K<%@)”,键路径,起始日期,键路径,结束日期)
    违约:
    newPredicate=谓词
    }
    }
    返回新谓词
    }
    
    多亏了威勒克的回答,我才得以解决。我想让您参与整个解决方案

  • 创建自定义类CustomRowTemplate:NSPredicateEditorRowTemplate
  • 重写func谓词,参见上面的Willeke代码。这可以访问您希望筛选的日期 它创建一个谓词,其中包含一天的日期/时间范围
  • 在属性检查器中,为谓词编辑器为keypath和date创建一个新的行模板。 然后将其类更改为CustomRowTemplate

  • 就这些


  • 一个
    NSPredicateEditorRowTemplate
    子类怎么样?是的,这是我的方法。但我正在努力创建一个templateView,保留两个输入字段。在Objective下,您可以操作模板的视图。现在templateViews()只是一个getter函数。您想要一个有两个日期的行,还是想要一个有一个日期的行和一个有两个日期的谓词?我想要一个有两个可编辑日期的行,这样我就可以将日期设置为“如何按天过滤”或“如何在这两个日期之间实现”的问题?您是如何操作Objective-C中模板的视图的?
    override func predicate(withSubpredicates subpredicates: [NSPredicate]?) -> NSPredicate {
        // call super to get the predicate, for example aDate == '3.5.20210 14:03:53'
        let predicate = super.predicate(withSubpredicates: subpredicates)
        // convert the predicate to aDate >= '3.5.2021 00:00:00' AND aDate < '4.5.2021 00:00:00'
        var newPredicate = predicate
        if let comparisonPredicate = predicate as? NSComparisonPredicate,
            let predicateDate = comparisonPredicate.rightExpression.constantValue as? Date {
            let keyPath = comparisonPredicate.leftExpression.keyPath
            var components = Calendar.current.dateComponents([.year, .month, .day], from: predicateDate)
            components.hour = 0
            components.minute = 0
            components.second = 0
            components.calendar = NSCalendar.current
            switch comparisonPredicate.predicateOperatorType {
                case .lessThan:
                    // aDate < '3.5.2021 00:00:00'
                    let date = components.date! as NSDate
                    newPredicate = NSPredicate(format: "%K < %@", keyPath,date)
                case .lessThanOrEqualTo:
                    // aDate < '4.5.2021 00:00:00'
                    components.day = components.day! + 1
                    let date = components.date! as NSDate
                    newPredicate = NSPredicate(format: "%K < %@", keyPath,date)
                case .greaterThan:
                    // aDate >= '4.5.2021 00:00:00'
                    components.day = components.day! + 1
                    let date = components.date! as NSDate
                    newPredicate = NSPredicate(format: "%K >= %@", keyPath,date)
                case .greaterThanOrEqualTo:
                    // aDate >= '3.5.2021 00:00:00'
                    let date = components.date! as NSDate
                    newPredicate = NSPredicate(format: "%K >= %@", keyPath,date)
                case .equalTo:
                    // aDate >= '3.5.2021 00:00:00' AND aDate < '4.5.2021 00:00:00'
                    let startDate = components.date! as NSDate
                    components.day = components.day! + 1
                    let endDate = components.date! as NSDate
                    newPredicate = NSPredicate(format: "%K >= %@ AND %K < %@", keyPath, startDate, keyPath, endDate)
                case .notEqualTo:
                    // NOT (aDate >= '3.5.2021 00:00:00' AND aDate < '4.5.2021 00:00:00')
                    let startDate = components.date! as NSDate
                    components.day = components.day! + 1
                    let endDate = components.date! as NSDate
                    newPredicate = NSPredicate(format: "NOT (%K >= %@ AND %K < %@)", keyPath, startDate, keyPath, endDate)
                default:
                    newPredicate = predicate
            }
        }
        return newPredicate
    }
    
        override func predicate(withSubpredicates subpredicates: [NSPredicate]?) -> NSPredicate